Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

91 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Interpreter

English | 中文

中英翻译模型,自建分词器,纯 PyTorch 实现。

本项目的使用流程,是从一个换过词表的 1.5B 底座训出中英互译模型,流水线 SFT → CPO → GRPO。 包含从下载语料到发布上 Hugging Face 的完整流程:数据构建、三阶段训练、评测、 导出发布。模型与训练代码(src/)只依赖 torch —— Qwen3 的 forward、LoRA、 Adafactor、GRPO 的策略梯度、safetensors 读写都是自己实现的。

这个仓库同时是一组 A/B 对照。 主线用自训的 Piece 分词器(81903), Qwen/ 用 Qwen3 原生 BBPE(151643),两边共享同一批数据、同一套超参与奖励, 只差底座和分词器。要回答的问题是:换掉词表之后,走完流水线能不能追上?

import torch
from transformers import AutoModelForCausalLM
from tokenizer import PieceTokenizerWrapper     # 发布包自带

tok = PieceTokenizerWrapper(".")
model = AutoModelForCausalLM.from_pretrained(".", torch_dtype=torch.bfloat16).cuda().eval()
人工智能正在深刻改变我们的生活方式。
  → Artificial intelligence is profoundly changing our way of life.
Machine translation has improved dramatically in recent years.
  → 机器翻译在近几年有了显著的进步。

模型

Hugging Face 分词器 WMT23 zh→en WMT23 en→zh
Interpreter-Qwen3-1.7B Qwen3 BBPE 20.31 / 0.8053 33.69 / 0.8540
Interpreter-Qwen3-1.7B-ReTok Piece(自训) 19.29 / 0.7986 32.46 / 0.8512

BLEU / COMET,COMET 是 Unbabel/wmt22-comet-da。前者的 zh→en COMET 与 1.8B 的 HY-MT1.5 打平(0.8053 vs 0.8052)。

两个底座不微调、直接 5-shot 的成绩(同协议,WMT21 demos):

分词器 WMT23 zh→en WMT23 en→zh
Qwen3-1.7B-Base Qwen3 BBPE 21.83 / 0.7950 41.15 / 0.8490
ReTok 底座(phase2_ckpt_v18_tie) Piece(自训) 17.44 / 0.7582 38.10 / 0.8255

不微调的 Qwen 底座 BLEU 比流水线产物还高 —— en→zh 41.15 → 33.69,掉 7.5 分, 换来 COMET +0.005。整条 SFT→CPO→GRPO 是拿词汇重合度换 COMET 的充分性,而 COMET 又正是 GRPO 的奖励。报提升要对着这两行报,不能只对着 SFT 报 —— 否则会把「补回自己造成的损失」说成「提升」。唯一四项全面超过 base 5-shot 的 是调过参的 SFT→GRPO(22.85 / 0.8003 · 41.97 / 0.8540)。

底座这两行有两套测量,差在 demo 选取和停止条件:上表是仓内可复现的那次, Summer 侧另测过 22.17 / 0.7958 · 42.85 / 0.8490(Qwen)和 19.60 / 0.7834 · 40.99 / 0.8377(ReTok)。COMET 几乎相同而 BLEU 差 0.3~2 分,仓内比较一律用 上表,别混。

huggingface-cli download Ismantic/Interpreter-Qwen3-1.7B-ReTok --local-dir ReTok
pip install git+https://github.com/Ismantic/PieceTokenizer
cd ReTok && python example_load.py

Piece 那个不是即插即用的 HF 模型 —— 分词器是编译的 C++ 扩展, AutoTokenizer 加载不了,发布包里带了 tokenizer.pyexample_load.py

效果

相对 Qwen 基线的 COMET 差(两个方向):

阶段 zh→en en→zh
SFT −0.0162 −0.0164
CPO −0.0076 −0.0027
GRPO −0.0036 −0.0029

换分词器在 SFT 阶段损失最大(约 −0.016),CPO/GRPO 把大部分差距补回来, 到 GRPO 时收窄到 −0.003 ~ −0.004。 这是这个项目的主要发现。

BLEU 不同步收窄,而且 GRPO 那行的大差距是路径差不是分词器差 —— 要纯比分词器效应看 CPO 那一行。详见 docs/WHY.md

代码

data/       下载 + 构建三阶段数据。source.py 是数据源注册表,唯一的真相来源
prepare/    编排:装依赖、分词、预编码、调训练、采样打分、评测
src/        模型 + 训练。只依赖 torch
save/       导出 HF 发布包 + 上传 + 与线上核对

外加 Qwen/(A/B 对照,自带 prepare/ src/ save/,共享根 data/)、 docs/test/make help 看命令,每层还有自己的 make help

两条不能破坏的分层约束:

  • src/ 只依赖 torch。 Qwen3 forward、LoRA、Adafactor、GRPO 的更新都是 自己实现的(替掉 transformers / peft / trl)。加依赖前先想能不能放 prepare/
  • src/ 不碰文本。 分词、对话模板、截断全在 prepare/encode.py, src/ 只读预编码好的 id。所以 PieceTokenizer 不是 src/ 的依赖。

Qwen/ 不受这两条约束 —— 那一层的价值是「别人用标准工具链能复现的基线」, 忠实比可读重要。

训练

make deps                            # 从 GitHub clone + 编译 PieceTokenizer
make -C data required                # 下载语料与模型资产
bash prepare/pipeline.sh             # SFT → CPO → GRPO
bash prepare/pipeline.sh sft_grpo    # SFT → GRPO(两步,跳过 CPO)
make test                            # 回归防线

两步和三步的 COMET 是打平的,而两步的 BLEU 高 2.5 / 8.3 分。 三步多花一次 CPO 训练,换来的是 en→zh BLEU 掉 8 分。两条都留着是因为 CPO 阶段本身是本项目 重要发现的来源。要复现最优模型走两步,要理解流水线走三步。

依赖

语料、底座、评分模型、C++ 扩展全部可从公网重建,不允许指向本机既有目录。 加新数据源必须在 data/source.py 登记公开出处;找不到出处的宁可不用。

相关

Summer 产出本仓库的底座:给 Qwen3-1.7B-Base 换词表(ReTok)
PieceTokenizer Piece 分词器的 C++ 实现与词表

文档

怎么跑看 make help,部署看 HF 上的 model card(发布包自带 example_load.py,cd 进去就能跑)。

License

Apache-2.0。训练数据源自 ALMA / X-ALMA 平行语料与 WMT 测试集, 底座源自 Qwen3-1.7B-Base,请一并遵守上游许可。

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages