从零复现EVIE-4.5B:8B教师模型双臂训练与Soup权重合并实战教程
从零复现EVIE-4.5B:8B教师模型双臂训练与Soup权重合并实战教程
本文带你从零复现 EVIE-4.5B——腾讯开源的轻量级视觉文档检索(Visual Document Retrieval)模型。你将亲手完成 8B 教师模型的双臂(two-arms)训练、Soup 权重合并,以及 Prefix-MRL + ARD 学生模型蒸馏全流程。整篇文章跟着官方脚本一步步执行,新手也能跑通。
EVIE(Evidence-Vector-Informed Embedding)采用 Late-Interaction 多向量范式:文档页面和查询文本都被编码为 token 级向量,通过 MaxSim 逐 token 匹配打分,因此能保留表格、图表、小字排版等细粒度视觉信息,在 ViDoRe V3 榜单上以 66.02 分登顶开源梯队。
仓库结构与复现路线一览
仓库本身就是"模型权重 + 完整训练管线"二合一,复现所需的每一环节都有对应目录:
| 模块 | 路径 | 作用 |
|---|---|---|
| 教师模型训练 | code/teacher/ | EVIE-8B 双臂训练 + Soup 合并入口 |
| 学生模型训练 | code/student/ | EVIE-4.5B Prefix-MRL + ARD 蒸馏 |
| 共享工具 | code/shared/ | 数据加载、权重合并、138 任务评测 |
| 压缩管线 | code/compress/ | 免训练 HAC token 压缩 |
| 检索引擎 | colpali/ | ColQwen3.5 模型实现与 ARD 损失 |
复现主线只需三条命令(来自 README.md):
bash code/teacher/run.sh # 第1步:训练8B教师双臂并合并Soup bash code/student/run.sh # 第2步:蒸馏4.5B学生模型 bash code/shared/eval_run.sh # 第3步:138任务全面评测环境准备:一键配置环境变量
克隆仓库并安装依赖:
git clone https://gitcode.com/tencent_hunyuan/EVIE-4.5B cd EVIE-4.5B pip install -r requirements.txt关键一步是初始化环境变量。仓库提供了模板 env.sh.example,它定义了四个核心路径变量:
DATA_ROOT/HARDNEG_ROOT:训练数据与难负例根目录(默认指向examples/toy玩具数据,真实训练需替换)RUNS_DIR:所有模型产出目录(checkpoint、Soup 模型)EVAL_ROOT:评测任务数据根目录EVIE_8B_DIR/TEACHER_DIR:教师模型权重位置
cp env.sh.example env.sh source env.sh这些路径由 code/shared/lib.sh 中的evie_workdirs统一解析,并禁止把 checkpoint 写进 venv 目录,避免常见坑。
第1步:8B教师模型双臂训练实战
什么是"双臂训练"?
EVIE-8B 并不是只训练一次,而是用同一套超参配方、不同难负例(hard-negative)数据分片并行训练两个模型,称为 Arm A 和 Arm B:
| 臂 | 运行名(默认) | 难负例分片 |
|---|---|---|
| Arm A | evie-8b-d4096_mvt1024_s42-judged | judged(人工/模型判定的精选难负例) |
| Arm B | evie-8b-d4096_mvt1024_s42-allpos | allpos(全部正例参与构造) |
编排逻辑全部写在 code/teacher/run.sh:脚本以for RUN_NAME in "$ARM_A" "$ARM_B"循环依次调用 code/teacher/scripts/launch.sh,任一臂失败则跳过合并直接退出,保证产物可追溯。
核心训练超参速查
两臂共用以下关键配置(默认值来自 launch.sh):
COL_DIM=4096:教师模型单头投影维度MVT=1024:最大视觉 token 数EPOCHS=1、EFF_BATCH=512(有效批大小,梯度累积自动计算)LR=4.57e-5、LORA_R=32、LORA_ALPHA=128(LoRA 微调)NUM_HARD_NEGS=2、HARDNEG_IN_BATCH_WEIGHT=0.5:难负例数量与 batch 内负例权重BIDIR=on:双向注意力(编码器化改造,Late-Interaction 的精髓)
底层训练脚本为 code/teacher/scripts/train.py,它基于ColbertNegativeCELoss对比损失,并用torch.distributed.run拉起多卡进程。
第2步:Soup权重合并——为什么默认α=0.4
两臂训练完成后,run.sh会自动调用 code/shared/merge_seeds.py 做Soup 合并:
- 将两个 LoRA adapter 分别
merge_and_unload到基座 Qwen3.5 上; - 对完整
state_dict按权重加权平均,教师默认ALPHA=0.4(Arm A 占 0.4,Arm B 占 0.6); - 以 float32 累加保证精度,最终存为 bfloat16,并写入
run_config.json记录soup_arms、merge_weights等元信息。
合并前脚本会做配方契约校验(CONTRACT字段列表):两臂的学习率、LoRA 配置、损失温度等任何一项不一致都会直接报错,从机制上杜绝"错误合并"。
💡 想扫更多权重组合?使用 code/teacher/merge_alpha.sh,设置
ALPHAS="0.3 0.4 0.5"即可批量生成多个 Soup 并逐个评测,找到最优 α。
合并产物输出到$RUNS_DIR/evie-8b-d4096_mvt1024_s42/,训练+合并+评测一条龙完成后可直接作为学生蒸馏的教师权重。
第3步:学生模型蒸馏(Prefix-MRL + ARD)
ARD损失:锚点保持的容量感知关系蒸馏
4.5B 学生从冻结的 8B 教师学习,核心是 colpali/colpali_engine/loss/ard.py 中的 ARD 损失,由三部分组成:
- Relation Distillation(
RELATION_WEIGHT=1.0):对齐师生 MaxSim 矩阵的行/列关系拓扑(KD_DIRECTIONS=both) - Margin Distillation(
MARGIN_WEIGHT=0.25):回归教师给出的难负例分数间隔 - Anchor Alignment(
ANCHOR_WEIGHT=0.25):用 EVIE-Preview 权重锚定 128D 前缀,防止低维退化
Prefix-MRL弹性多头
学生只训练一个 2048D 线性投影,运行时可自由截断为 64/128/256/512/1024/2048 维,无需维护多套模型。相关配置集中在 code/student/run.sh:
export TEACHER_DIR=../Evie-8B # 指向第2步合并出的教师模型 bash code/student/run.sh学生同样是双臂结构(allpos+judged),但合并策略是等权平均(不带--weights,即full_state_dict_mean),基座为tencent/EVIE-Preview-4.5B热启动,学习率降为1.5e-5(见 code/student/scripts/launch.sh)。
验证成果:评测与HAC压缩
一键评测
评测统一走 code/shared/eval_run.sh,它会自动读取run_config.json中的head_dims,对每个前缀维度分别跑评测并输出到eval/d{dim}/summary.json,最后用aggregate_heads.py汇总。完整 138 任务矩阵(ViDoRe V1/V2/V3 + JinaVDR)参考输出:EVIE-4.5B 在 nDCG@10 上取得 V1 92.53 / V2 74.91 / V3 66.02。
先玩demo再上生产
没有大评测集?仓库内置了 8 页文档的演示,跑一下就能直观看到检索效果:
bash examples/demo/run.sh它会对 examples/demo/pages/ 下的 8 张文档页(财报、发票、架构图、报错日志等)做嵌入与 MaxSim 打分。
可选:HAC token压缩
原始表示每页约 750 个向量,code/compress/run.sh 提供免训练 HAC(层次凝聚聚类)压缩,默认配方d64 × K32把每页压到 32 个向量,百万页索引仅 3.81 GiB,同时保留 73.47 的 Avg4 分数——生产部署强烈推荐。
常见问题排查
| 现象 | 原因与解法 |
|---|---|
[fatal] set DATA_ROOT | 未source env.sh,或DATA_ROOT仍指向 toy 数据(正式训练需换成真实 dump) |
recipe mismatch合并报错 | 两臂超参不一致,检查COL_DIM、SEED、难负例分片是否按默认配对 |
| 输出目录非空被拒 | 脚本默认拒绝覆盖半成品,OVERWRITE=1强制重跑,旧目录会自动归档 |
| 显存不足 | 调小BSZ、开GRAD_CHECKPOINTING=on;多节点时通过NNODES/MASTER_ADDR扩展 |
| 想只训一臂省资源 | ARMS="a" DO_MERGE=0(学生脚本)即可跳过 B 臂与合并 |
总结
至此你已经完整走通了 EVIE-4.5B 的复现链路:双臂差异化训练 → Soup 加权合并 → ARD 蒸馏 → 多头评测 → HAC 压缩。这条管线设计得非常工程化:契约校验防错、断点续跑、rank 0 统一合并、评测自动聚合,非常适合学习大模型检索系统的训练最佳实践。动手前先把env.sh配好,从 teacher 开始,一条命令一个阶段,稳定且可复现。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考