【免费下载链接】plamo-2-translate
plamo-2-translate 是 PLaMo 2 Translate(Preferred Networks 的翻译专用大模型)在 Apple Silicon 上的 4-bit MLX 转换版。它的Plamo2Tokenizer借助 Aho-Corasick 自动机与 numba JIT 编译,把 10 万级词表的分词压缩到接近线性时间,是理解大词表高速分词的优秀范例。
⚡ 为什么 10 万词表需要"高速分词"
在翻译场景中,一条提示词可能包含数千个 token;如果分词速度跟不上,GPU 会大量时间空等 CPU。plamo-2-translate 的模型配置中,词表规模达到100,032(见 config.json 的vocab_size字段),其中还包含 256 个<0xXX>字节兜底 token。
模型关键参数一览:
| 参数 | 值 | 出处 |
|---|---|---|
| 词表大小 | 100,032 | config.json |
| 量化 | 4-bit affine(group size 64) | config.json |
| 隐藏层 / 层数 | 4096 / 32 | config.json |
| 分词器类 | Plamo2Tokenizer | tokenizer_config.json |
| 验证吞吐(M1 Max) | 解码约 51.4 tokens/s | evaluation.json |
💡 分词发生在模型推理之前:token 数直接影响 prompt 长度和上下文占用,分词方式还会改变模型看到的"语义单元"。
🔍 Plamo2Tokenizer 的不同之处:基于分数(score)的分词
多数分词器(如常见 BPE)按"最长匹配"切分文本,而 PLaMo 系列的分词更精细:词表中每个 token 都带有一个分数,分词时要在所有合法切分中,选择让"总分数最大"的那一条路径。
词表文件 tokenizer.jsonl 为逐行 JSON,每行形如["token", score](本仓库中该文件约 10.5 MB,通过 Git LFS 拉取),整个分词器的实现集中在 tokenization_plamo.py。
关键入口非常简洁:
- tokenization_plamo.py#L342-L344:
_tokenize(text)直接委托给AhoCorasick.encode_as_tokens - tokenization_plamo.py#L240-L305:
Plamo2Tokenizer.__init__中一次性读取词表并调用aho_corasick.build构建自动机
也就是说:构建一次、分词无数次。自动机只依赖词表,构建完成后可以反复复用,序列化(pickle)时还会在反序列化时自动重建(见 tokenization_plamo.py#L310-L318 的__getstate__/__setstate__)。
特殊 token 定义见 special_tokens_map.json:
| Token | 含义 |
|---|---|
<\|plamo:unk\|>(0) | 未知 token |
<\|plamo:bos\|>(1) | 句首;同时作为 EOS ID 之一 |
<\|plamo:eos\|>(2) | 句尾 |
<\|plamo:pad\|>(3) | 填充 |
<\|plamo:op\|>(4) | 翻译操作分隔符,也是 EOS ID |
🚀 Aho-Corasick 如何加速 10 万词表匹配
AhoCorasick类(tokenization_plamo.py#L32-L237)是整个分词器的心脏,分四步理解:
1️⃣ 把词表压成一张"扁平表"
build()(tokenization_plamo.py#L70-L142)把每个 token 及其所有后缀注册进 Trie,并展平成一块 4 列的int32numpy 数组(_table)。每一行(piece)记录:片段长度、token ID、分数(×1e4 取整)、后继片段的 ID。
两个小巧思值得学习:
- 64 位边编码:用"首字符 codepoint 高 32 位 + 后缀 ID 低 32 位"拼成单个整数作字典键,查表只需一次哈希;
- 局部性排序:后缀按"倒序字符串的字典序"排列,配合从文本末尾向前扫描的访问模式,显著提升内存访问连续性。
2️⃣ 动态规划:从末尾回溯选最优路径
核心热点函数_encode(tokenization_plamo.py#L144-L220)被@njit装饰后由 numba 编译为机器码。算法从文本末尾向前扫描,维护一个 DP 数组:scores[i]表示"从位置 i 编码到末尾"的最小代价。对每个位置,自动机会枚举所有能在该位置匹配的候选 token,取scores[i+长度] - 分数最小的路径;同分平局时优先更长片段(表内片段按长度降序存储,天然实现该偏好)。
这正是"分数化分词"能高效运转的原因——匹配和选路在同一次遍历里完成,总开销近似 O(文本长度 × 候选数),而非 O(文本长度 × 10 万词表)。
3️⃣ 字节兜底:任何字符都不丢失
若某个位置没有任何 token 可匹配(走到哨兵行UNKNOWN_SCORE),算法退回 UTF-8字节 token:词表中的 256 个<0x00>~<0xFF>恰好覆盖全部字节(tokenization_plamo.py#L90-L103 专门处理并断言其完整性)。多字节字符会被拆成 2~4 个字节 token(见 tokenization_plamo.py#L207-L214),保证encode永远可逆、不报错。
4️⃣ 输入表示:UTF-32 一次到位
encode(tokenization_plamo.py#L222-L233)先把字符串按 UTF-32 转成 codepoint 数组再传入 JIT 函数,避免热点循环里反复解码 UTF-8。
📦 快速上手:mlx-lm 运行分词与翻译
依赖与安装(Apple Silicon,Python 3.13 验证):
pip install 'mlx-lm==0.31.2' 'transformers>=4.46,<5' numba加载模型并分词(自定义分词器需要trust_remote_code):
from mlx_lm import load model, tokenizer = load( "mlx-community/plamo-2-translate", tokenizer_config={"trust_remote_code": True}, ) print(tokenizer.encode("This is a short sentence.")) print(tokenizer.decode(tokenizer.encode("你好,世界!"))) # 触发字节兜底完整翻译用法(含语言标签的 chat template)见 README.md。该模板由 chat_template.jinja 定义,支持input lang=.../output lang=...显式指定翻译方向,比自动检测更适合可复现的对比评测。
⚠️ 注意:该 checkpoint 面向 MLX 运行时,加载器必须遵循 config.json 中的
model_file指向 modeling_mlx_plamo2.py;忽略该文件的运行时可能产生不同结果。
📂 核心文件地图
| 文件 | 作用 |
|---|---|
| tokenization_plamo.py | Plamo2Tokenizer+AhoCorasick完整实现(本文主角) |
| tokenizer.jsonl | 100,032 词条表:[token, score],Git LFS 存储 |
| tokenizer_config.json | 分词器配置与内置 chat template |
| chat_template.jinja | 翻译对话模板(含语言标签分支) |
| config.json | 模型配置:词表、量化、RoPE、Mamba/SSM 参数 |
| modeling_mlx_plamo2.py | MLX 模型实现(修正上游 RoPE 与 SSM 细节) |
| evaluation.json | M1 Max 上的验证数据(chrF 73.77、NLL 0.4595) |
| special_tokens_map.json | 特殊 token 映射 |
| LICENSE | PLaMo 社区许可证(含 en / ja 版本) |
小结:这套设计能学到什么
- 分数化分词:词表带 score,用 DP 选"总分数最大"的切分路径,比最长匹配更贴近训练分布;
- Aho-Corasick + 扁平表:一次遍历同时完成"匹配所有候选 token"与"选路",把 10 万词表的分词做到线性开销;
- numba
@njit:热点循环零 Python 解释开销,构建成本只在加载时发生一次; - 字节兜底
<0xXX>:256 个字节 token 保证任意 Unicode 文本都能编解码,永不抛错。
如果你正在为大词表模型(尤其中日韩翻译模型)设计推理管线,tokenization_plamo.py 的 400 行代码就是一份可以直接借鉴的"高速分词器"参考实现。
【免费下载链接】plamo-2-translate
相关推荐
如何快速上手 plamo-2-translate:5分钟在 Apple Silicon 上跑通 PLaMo 2 Translate 本地英日翻译
如何快速上手 plamo 2 translate:5分钟在 Apple Silicon 上跑通 PLaMo 2 Translate 本地英日翻译 plamo 2
玩转PLaMo 2双语翻译:用plamo-2-translate-bf16的input lang与output lang提示词精准控制英日翻译方向
玩转PLaMo 2双语翻译:用plamo 2 translate bf16的input lang与output lang提示词精准控制英日翻译方向 plamo
1Backend安全架构解析:访问令牌与配额管理的实现原理
1Backend安全架构解析:访问令牌与配额管理的实现原理 1Backend是一个用于构建AI应用或任何应用的开源框架,它通过可扩展的微服务和微前端架构,为开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考