LFM2.5-8B-A1B 原地词表扩充实战:65K→128K,不重训模型 · 干货攻略
- 链接: https://x.com/maximelabonne/status/2079582400019931633
- 分类: x-tips
- 来源: X @maximelabonne
- 作者: Jay
- 更新: 2026-07-29
这是什么
Liquid AI 在 2026 年 7 月公开了一套原地词表扩充(Tokenizer Expansion)配方,将已训练好的 LFM2-8B-A1B 模型的 BPE 分词器从 65,536 词扩充到 128,000 词,全程无需从头重训,最终产出 LFM2.5-8B-A1B 模型。
核心思路:把新词表设计为旧词表的确定性扩展——每个新 token 都能拆解为一个或多个旧 token,embedding 直接从旧 token 均值初始化,不需要随机初始化,也不需要跨词表对齐。
论文作者包括 Jimmy Smith、Tarek Dakhran、Maxime Labonne 等,发表于 arXiv 2607.15232(2026 年 7 月 16 日提交)。模型权重与扩充后的 128K 词表已在 Hugging Face 开源(LiquidAI/LFM2.5-8B-A1B),部署指南覆盖 llama.cpp、MLX、vLLM、SGLang 四种运行时。
为什么值得关注
小模型的词表困境
大语言模型的 tokenizer 在预训练前就固定了,词表按训练语料的语种分布分配。英语和代码占主导的语言得到最短的 token 切分,而印度语、泰语、越南语等在训练时覆盖不足的语言,每个词被切成大量碎片 token。
这不只是"看着不优雅"的体验问题——模型的 decoder 每生成一个 token 就要跑一次前向传播,token 越多,延迟、算力、能耗越高。对于端侧小模型,问题更严峻:
- 云端大模型:embedding + LM-head 矩阵占总参数比例极小,放大词表代价可控。
- 端侧小模型(参数量 8B 级):LM-head 在 batch size=1 时主导内存带宽,每步都要读完整词表。词表越大,内存搬运越多。
所以端侧模型通常维持 6-8 万的小词表,接受部分语言被"碎片化"的代价。
传统解法的代价
| 方案 | 代价 |
|---|---|
| 重新预训练 + 新词表 | 丢弃已有训练 compute,代价极高 |
| 直接替换为第三方词表 | 零样本迁移极难,需要额外对齐研究 |
Liquid AI 的配方走的是中间路线:自己掌控词表设计权,在旧词表基础上做确定性扩展,保留已有训练成果,同时解决多语言覆盖问题。
核验过程
本攻略所有命令、数字、结论均来自以下官方来源,并经第三方交叉验证:
官方来源(已读全文)
-
Liquid AI 官方博客 — Tokenizer Expansion: Upgrading a Model's Tokenizer in Place - 完整 pipeline 描述、两阶段适应细节、各语言 token 压缩比、per-token 成本数据、设备对比数据、质量恢复曲线 - 所有核心数字来源
-
arXiv 2607.15232 — In-Place Tokenizer Expansion for Pre-trained LLMs - Abstract 验证:泰语 4.0× / 印地语 2.4× / 越南语 2.6× 压缩比,2.2-3.7× per-char decode 加速 - 两阶段适应(embedding-only 600B tokens + full continued pretraining 400B tokens) - Hugging Face 权重与 128K tokenizer 下载地址确认
-
Hugging Face — LiquidAI/LFM2.5-8B-A1B - 开放权重确认,LFM Open License v1.0 许可证,部署指南覆盖列表
交叉验证
- AlphaSignal 报道(Liquid AI's LFM2.5 Upgrades Its Own Tokenizer, Hitting 3.7x Faster On-Device Speed):关键数字(泰语 4.0×、印度语 2.4×、越南语 2.6×、孟加拉语 3.4×、2.2-3.7× per-char 加速)与官方博客完全一致。
关于原帖与官方来源的差异说明
原帖 @maximelabonne 提到"印地语 2.4 倍 / 越南语 2.6 倍 / 泰语 4 倍",并估计 2.2-3.7 倍训练加速。经核验,2.2-3.7× 是 per-character decode 加速,不是训练加速(解码端侧速度收益);训练侧的两阶段适应共消耗 600B + 400B = 1T tokens 的适应训练。原帖未说明这是 decode 收益,攻略已按官方文档纠正此细节。
上手步骤
1. 获取模型与 tokenizer
# Hugging Face 下载完整模型(含扩充后的 128K tokenizer)
git lfs install
git clone https://huggingface.co/LiquidAI/LFM2.5-8B-A1B
# 或用 huggingface_hub
python -c "from huggingface_hub import snapshot_download; snapshot_download('LiquidAI/LFM2.5-8B-A1B')"
模型目录下包含标准 tokenizer.json 与 tokenizer_config.json,可直接用于下游推理框架。
2. 部署(参考官方支持的四种运行时)
llama.cpp(CPU/本地推理)
# 将 Hugging Face 格式转为 llama.cpp 格式(.gguf)
llama-cli -m LFM2.5-8B-A1B-Q4_K_M.gguf -p "用泰语写一句问候"
MLX(Apple Silicon)
# MLX-LM 示例(macOS)
from mlx_lm import load, generate
model, tokenizer = load("LiquidAI/LFM2.5-8B-A1B")
response = generate(model, tokenizer, prompt="泰语问候", max_tokens=128)
vLLM
vllm serve LiquidAI/LFM2.5-8B-A1B \
--tensor-parallel-size 1 \
--max-model-len 128000
SGLang
python -m sglang.launch_server \
--model-path LiquidAI/LFM2.5-8B-A1B \
--port 30000
3. 验证 tokenizer 词表大小
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("LiquidAI/LFM2.5-8B-A1B")
print(f"词表大小: {tokenizer.vocab_size}")
# 预期输出: 128000
# 对比测试(泰语 token 压缩效果)
text = "สวัสดีครับ" # 泰语"你好"
old_tokens = 5 # 旧 65K tokenizer 估计值
new_tokens = len(tokenizer.encode(text))
print(f"泰语 '{text}' -> 旧 tokenizer 约 {old_tokens} tokens, 新 tokenizer {new_tokens} tokens")
4. 定量评估(可选)
from transformers import AutoModelForCausalLM
# 在新 tokenizer 上评估基准任务
model = AutoModelForCausalLM.from_pretrained("LiquidAI/LFM2.5-8B-A1B")
tokenizer = AutoTokenizer.from_pretrained("LiquidAI/LFM2.5-8B-A1B")
langs = {
"Thai": "สวัสดีครับ",
"Hindi": "नमस्ते",
"Vietnamese": "Xin chào",
"English": "Hello, how are you?",
}
for lang, text in langs.items():
old_count = 3 # 旧 tokenizer 估计 token 数(示意)
new_count = len(tokenizer.encode(text))
ratio = old_count / new_count
print(f"{lang}: {old_count} -> {new_count} tokens ({ratio:.2f}x fewer)")
注意:以上评估代码中旧 tokenizer 的 token 数是示意参考值,实际对比需准备旧版 tokenizer 权重。
坑与适用边界
✅ 这个方法适合你的场景
- 你掌控模型的 tokenizer 设计(能访问原始 BPE merge 规则和特殊 token 配置)。
- 已有训练好的 checkpoint,想扩充多语言支持但不想从头重训。
- 目标模型是端侧或资源受限场景,per-character decode 速度比 per-token 精确度更重要。
- 模型后续还有 mid-training / post-training 阶段(两阶段适应可无缝插入现有 pipeline)。
❌ 这个方法不适用的场景
- 想换成一个完全不同的第三方 tokenizer(这不是在"扩展"而是在"替换",需要用零样本 tokenizer 迁移方法,论文 Minixhofer et al., 2024 有专门讨论)。
- 模型没有源码 tokenizer,无法继续原有的 BPE merge 链。
- 对延迟极敏感且主要语言是英语/代码(因为 128K 词表带来了 7-10% 的 per-token 减速,而英语/代码压缩比基本不变,会受到纯粹的性能惩罚,上限约 -9%)。
⚠️ 关键工程细节
- 128K 是甜点,不是越高越好:实验显示继续扩到 256K 时,在手机(Snapdragon 8 Elite)上 per-token 成本惩罚高达 37%,而额外压缩收益远不能弥补。
- 两阶段缺一不可:直接全参数训练会让原有能力退化约 6 个 aggregate 点;只有先冻结主体训练 embedding,等新 token 在 embedding space 站稳,再解冻全参数继续预训练,质量才能完全恢复甚至超过原模型。
- Global-MMLU 的具体涨幅:印度语 +7.6、越南语 +11.6、印尼语 +9.1(5-shot,chance=25% 基线)。这是新增的 RL/mid-training 阶段的综合效果,不仅仅是 tokenizer 功劳。
- embedding 绑定:LFM2.5-8B-A1B 使用 tied embedding(输入输出共享矩阵),所以 embedding 层更新一次即可同时影响编码器和解码器。
一句话结论
在已训练的 checkpoint 上原地扩充 BPE 词表(65K→128K),用两阶段适应(仅 embedding + 全参数继续预训练)让模型在不丢弃原有能力的前提下,泰/印地/越南等语言 token 压缩 2.4-4 倍,per-character 解码速度提升 2.2-3.7 倍,是端侧小模型多语言化的最高性价比路径。
参考链接
- 官方博客:https://www.liquid.ai/blog/tokenizer-expansion
- arXiv 论文:https://arxiv.org/abs/2607.15232
- Hugging Face:https://huggingface.co/LiquidAI/LFM2.5-8B-A1B
- 原帖:https://x.com/maximelabonne/status/2079582400019931633