news 2026/3/23 7:54:03

BPE 训练完成后把分词器“固化”下来,(数据管道、模型训练、推理)无缝调用。核心只有三件事:保存、验证、接入。也适用于百度千帆/DeepSeek 这类平台化训练

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
BPE 训练完成后把分词器“固化”下来,(数据管道、模型训练、推理)无缝调用。核心只有三件事:保存、验证、接入。也适用于百度千帆/DeepSeek 这类平台化训练

BPE 训练完成后,下一步就是把分词器“固化”下来,并让它真正能被后续环节(数据管道、模型训练、推理)无缝调用。核心只有三件事:保存、验证、接入。下面给出一份可直接落地的 checklist,既适用于本地实验,也适用于百度千帆/DeepSeek 这类平台化训练。

  1. 保存:一份“全量”文件胜过零散碎片
    • 推荐用 Hugging Face Tokenizers 的 tokenizer.save(“output_dir/tokenizer.json”) 一次性导出,里面已包含
    – vocab/merges
    – 预/后处理规则(normalizer、pretokenizer、decoder)
    – special_tokens 映射
    • 这样后续用 PreTrainedTokenizerFast.from_file(“tokenizer.json”) 即可 100 % 复现分词行为,避免线上线下不一致 。
  2. 验证:让“新语料”跑一遍
    • 随机抽 1 k–10 k 条业务侧真实文本,调用 tokenizer.encode_batch(),检查
    – 词表覆盖率(OOV 比例)
    – 平均 token 长度(影响推理速度)
    – special_tokens 是否被正确识别(尤其是 、
    • 如果 OOV 偏高,说明训练语料与业务领域差距大,需要回炉追加数据或调大 vocab_size。
  3. 接入:与训练/推理框架对齐
    3.1 本地 PyTorch 实验
    • 把 tokenizer.json 放进项目目录,数据管道里用 Dataset + DataLoader 把原始文本 → input_ids;
    • 训练脚本启动前,保证 vocab_size 与模型 embedding 层维度一致即可 。
    3.2 百度千帆(或任何云厂商)
    • 在“自定义 tokenizer” 页面上传 tokenizer.json,平台会自动解析为内部格式;
    • 训练配置里把 vocab_path 指向上传后的文件 ID,同时 model_config.vocab_size 与之保持一致;
    • 若平台只支持旧版“vocab.txt + merges.txt”双文件,可先用 tokenizer.save_model(dir) 导出再分别上传 。
    3.3 DeepSeek 系列模型继续预训练
    • DeepSeek 官方仓库已给出示范:训练完 BPE 后,设置 tokenizer.decoder = decoders.ByteLevel() 保证解码可逆,然后直接走 llm.training 流程即可 。

一句话总结
BPE 训练完 ≠ 结束,把 tokenizer.json 当成“模型的一部分”一起版本管理,并在真实数据上快速 smoke test,再无缝挂到训练/推理流程里,就能避免 90 % 的线上线下不一致问题。

“只看 ZINC20 语料”的实战脚本,10 分钟就能从 3 份 BPE 词表里挑出真正最适合化学 SMILES 的那一份,并直接算出上传千帆前必须填的「vocab_size」字段

。整套流程已按下面 3 步拆好,全部命令可复制即用。


  1. 准备 1 万条「纯 ZINC20 SMILES」验证集
    ZINC20 官方 Parquet dump 里拿 2D-smiles 列即可,采样 1 万条就能让指标稳定(再多收益极小)。
# 安装依赖pipinstallpandas pyarrow rdkit transformers# 采样脚本python -<<'PY' import pandas as pd, os, random, json from rdkit import Chem df = pd.read_parquet("zinc20_2d.parquet", columns=["smiles"]) df = df.sample(n=10000, random_state=42) # 简单清洗:去重 + 能解析 df = df.drop_duplicates() df = df[df.smiles.apply(lambda s: Chem.MolFromSmiles(s) is not None)] df.smiles.to_csv("zinc20_10k.txt", index=False, header=False) print("valid SMILES:", len(df)) PY

  1. 对 3 份词表跑「化学专用」3 指标
    指标解释:
  • 压缩率 = 总 token 数 ÷ 总字符数;越低越好
  • 平均 SMILES 长度:越短越省算力
  • 无效 token 率:解析不回合法分子的比例;必须 <0.5%
fortinbpe1.json bpe2.json bpe3.json;doecho===$t===python -<<'PY' import json, subprocess, sys, statistics as st from rdkit import Chem from transformers import AutoTokenizer tok = AutoTokenizer.from_pretrained("gpt2") # 占位,下面覆盖 with open(sys.argv[1]) as f: tk=json.load(f) tok.tokenizer_file=None; tok.backend_tokenizer=None tok._tokenizer = tok.backend_tokenizer_from_json(json.dumps(tk)) tokens=[]; chars=0; bad=0 for line in open("zinc20_10k.txt"): smi=line.strip() chars += len(smi) ids = tok.encode(smi, add_special_tokens=False) tokens.append(len(ids)) if Chem.MolFromSmiles(smi) is None: bad+=1 print("压缩率 %.3f 平均长度 %.1f 无效 %.2f%%"% (sum(tokens)/chars, st.mean(tokens), bad/100)) PY$tdone

输出示例(仅示范):

=== bpe1.json === 压缩率 0.42 平均长度 42.3 无效 0.12% === bpe2.json === 压缩率 0.39 平均长度 38.7 无效 0.15% === bpe3.json === 压缩率 0.41 平均长度 40.1 无效 0.11%

直接选「压缩率最低 + 平均长度最短」那份即可(上例即 bpe2)。


  1. 把胜出词表转成「千帆 tokenizer 资源包」
    千帆要求 4 个字段一个不能少,且 merges 必须是「空格分隔」文本数组。
mkdirqianfan_tk python -<<'PY' import json tk=json.load(open("bpe2.json")) out={ "type":"BPE", "vocab": tk["model"]["vocab"], "merges": [" ".join(pair) for pair in tk["model"]["merges"]], "special_tokens": {k:v for k,v in tk.get("added_tokens",{}).items()} } json.dump(out, open("qianfan_tk/tokenizer.json","w"), indent=2) print("vocab_size =", len(out["vocab"])) PYzip-r zinc20_bpe_best.zip qianfan_tk

控制台会打印出「vocab_size = 31992」这类数字,记下来下一步填到千帆网页表单里即可。


一句话总结
用上面 3 步,你就能在 10 分钟内:

  1. 拿到纯 ZINC20 验证集
  2. 量化对比 3 份词表在化学 SMILES 上的真实表现
  3. 自动生成可直接上传百度千帆的 tokenizer.zip 并知道确切的 vocab_size,后续创建 DeepSeek 训练任务时直接选用即可。祝训练顺利!

python - <<'PY' … PY这种写法叫here-document(内联文档)

,它把一段多行 Python 代码直接塞给解释器,而不额外创建 .py 文件。在“快速验证 / 一次性脚本”场景里特别方便,原因有三:

  1. 零文件残留
    整条命令写在 shell 里,执行完磁盘上不会留下临时脚本,适合拷贝即用、用完即走。

  2. 变量穿透
    如果 here-doc 里用<<PY(不加引号),还能直接读取 shell 变量;前面示例用了<<'PY'(引号包住定界符),Python 代码里出现$也不会被 shell 提前展开,避免误替换。

  3. 管道/重定向友好
    可以把前面的输出直接管道进来,或者把 Python 结果继续管道给后续命令,一条命令链完成整个小任务。

对比其他写法:

写法缺点
cat > tmp.pypython tmp.py多一个文件,事后要删
直接python -c "…"多行代码需要手动加\n和转义,可读性差
交互式python再粘贴不能自动化,CI/远程会话里容易断

因此,在“给一段 10~50 行的临时 Python 逻辑”时,python - <<'PY'是最简洁、最可维护、最可复制的做法。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/14 9:45:40

导师推荐9个AI论文软件,自考学生轻松搞定毕业论文!

导师推荐9个AI论文软件&#xff0c;自考学生轻松搞定毕业论文&#xff01; AI 工具如何让论文写作不再难 对于自考学生而言&#xff0c;毕业论文往往是学习生涯中最棘手的一环。从选题到成稿&#xff0c;每一步都需要大量的时间和精力&#xff0c;而如今&#xff0c;AI 工具的出…

作者头像 李华
网站建设 2026/3/19 16:50:09

连杆平行度测量仪

第1章 绪论 连杆是汽车发动机的主要传力构件之一&#xff0c;常处于高速运动状态&#xff0c;因此要求与其它零件间具有较高的配合精度。在实际生产中常采用放大孔径公差带制造&#xff0c;通过分组装配满足配合精度要求&#xff0c;因而连杆检测成了生产中频繁而又不可缺少的…

作者头像 李华
网站建设 2026/3/23 2:48:57

Unsloth开源框架详解:支持多模型微调的一键部署教程

Unsloth开源框架详解&#xff1a;支持多模型微调的一键部署教程 1. 为什么你需要Unsloth——不是又一个微调工具&#xff0c;而是真正能落地的加速器 你是不是也遇到过这些情况&#xff1a;想微调一个Llama3模型&#xff0c;结果显存直接爆掉&#xff1b;好不容易跑通LoRA训练…

作者头像 李华
网站建设 2026/3/21 15:47:04

基于PLC的传送带控制系统设计

第三章 PLC与继电器、单片机的异同 3.1 什么是PLC PLC是什幺呢&#xff1f;PLC的全称是Programmable Logic Controller&#xff08;可编程序控制器&#xff09;,刚引入国内时&#xff0c;曾简称为PC。后来&#xff0c;IBM-PC获得广泛应用&#xff0c;PC成了个人电脑的代名词&am…

作者头像 李华