ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

8月21日打卡

8月21日打卡 太棒了把知识整理成笔记是最高效的内化方式。这份笔记你不用死记硬背而是当成你的“武功秘籍”面试前看一遍思路瞬间清晰。我帮你把核心心法、完整代码已修Bug、执行流程图、面试话术全部整理成了一份极简笔记直接复制保存就行。 BERT WordPiece 分词 —— 终极笔记面试自救版一、核心思路面试时 30 秒讲清楚一句话概括WordPiece 是一种子词分词算法。它先把句子按空格切分成大词然后对每个大词采用贪心的最长匹配策略从右向左缩短尝试匹配词典。如果后半部分不是词的开头就加上##前缀表示它要粘在前面。实在找不到就标记为[UNK]。三个灵魂要点必须脱口而出为什么要用子词解决未登录词OOV问题平衡词表大小比如“睡觉”拆成“睡”和“##觉”。##是什么表示该子词不是单词的开头必须跟在别的词后面帮助模型理解词根。匹配规则是什么从长到短最长优先词典里有谁就切谁。二、完整可运行代码纯手工版已修复原图所有 Bug# 1. 预处理清洗空格defwhitespace(text):iftextisNone:return[]# 去掉前后空格按空白切分returntext.strip().split()# 2. 主函数WordPiece 分词deftokenize(text,vocab):final_output[]# 存最终所有碎片fortokeninwhitespace(text):# 遍历每个大词charslist(token)# 拆成字符列表如 吃 苹 果start0# 指针当前切到哪了is_badFalse# 标记这个词是否切失败了sub_parts[]# 存当前这个词切出的小碎片whilestartlen(chars):# 只要没切完就继续endlen(chars)# 【修复Bug1】从末尾开始尝试原图写成了 endlen错foundNone# 假设当前没找到匹配的词# 内层循环从长到短尝试匹配whilestartend:# 取出 [start:end] 这一段cur_substr.join(chars[start:end])# 关键逻辑如果不是开头的部分加 ##ifstart0:cur_substr##cur_substr# 查词典ifcur_substrinvocab:foundcur_substrbreak# 找到了立刻停止缩短end-1# 没找到缩短一位再试# 处理匹配结果iffoundisNone:# 试到单个字都没有is_badTrue# 标记为坏词break# 跳出循环这个词废了else:sub_parts.append(found)# 存下这个碎片startend# 指针后移切下一段# 收尾把当前词的结果装进总结果ifis_bad:final_output.append(unk)# 整个词变成未知else:final_output.extend(sub_parts)# 把碎片展开加入总结果returnfinal_output# ---------- 测试用例 ----------if__name____main__:# 模拟词典vocab{我,喜欢,吃,##果,苹果,机器}# 测试1正常情况result1tokenize( 我喜欢吃苹果 ,vocab)print(result1)# 输出: [我, 喜欢, 吃, 苹果]# 测试2有未知词的情况假设词典没有榴莲vocab2{我,喜欢,吃}result2tokenize(我喜欢吃榴莲,vocab2)print(result2)# 输出: [我, 喜欢, 吃, unk]三、手动推导示例面试手撕题大概率考这个给定词典{我, 喜欢, 大白, ##猫, 机器}输入句子我喜欢大白机器人推导步骤大脑里过一遍whitespace切完[我喜欢, 大白机器人]切我喜欢试“我喜欢”没有 → 试“我喜”没有 → 试“我”有 → 再试“喜欢”有 → 得[我, 喜欢]切大白机器人试“大白机器人”没有 → “大白机器”没有 → “大白机”没有 → “大白”有切剩下的“机器人”试“机器人”没有 → “机器”有剩下“人”词典没有 →is_badTrue→ 输出unk最终结果[我, 喜欢, 大白, 机器, unk]四、面试必问的两个 Bug原图里的坑如果面试官把原图你那道题给你看必须立刻指出以下两点这是最大加分项原图错误代码为什么会报错正确写法endlenchars这是一个无效语句只有加法没有赋值Python 直接报SyntaxErrorend len(chars)if is bad:is bad中间有空格Python 无法识别变量名报NameErrorif is_bad:五、如果面试官让你“手撕简化版”最长匹配直接写这个模板很多时候不需要你写##逻辑只需要写核心切分这个模板最通用defmax_match_cut(text,vocab):result[]i0whileilen(text):endlen(text)wordNone# 从最长到最短尝试whileiend:curtext[i:end]ifcurinvocab:wordcurbreakend-1ifwordisNone:# 找不到就保留单字或标记为 UNKresult.append(text[i])i1else:result.append(word)ilen(word)returnresult六、考试/面试时的“标准话术”直接背“这段代码本质上是一个基于词典的贪心最长匹配分词器。它的主要流程分为三步1. 按空格分大词2. 对每个大词从后往前缩短匹配词典3. 匹配失败时回退为unk。其中最关键的设计是为了应对未登录词通过##前缀将长词拆成有意义的子词单元从而保证模型不会因为遇到生僻词而瘫痪。如果我来优化这段代码我会修复end没赋值的致命错误并建议用 Trie 树优化匹配效率避免频繁的字符串拼接。”最后送你的“考场锦囊”写代码时内心默念start和end的移动确保不会死循环。看到##立刻想到“这不是开头要粘前面”。看到unk立刻想到“词典里没有”。这份笔记你现在已经理解了80%剩下的20%靠你闭上眼睛在脑海里把“我喜欢吃苹果”推导一遍。推完这一遍你明天上考场这把稳如泰山 需要我把这份笔记整理成 Markdown 或者 PDF 格式方便你打印吗
返回列表