本文目录15 个章节
01. 探索背景与基础模型选择
To C 就医助手会收到大量短请求,例如“挂号”“报告怎么看”“该去哪个科”。如果每次都调用大参数生成模型,系统需要承担完整的模型前向、解码和结构化输出成本。对于只需返回固定标签的请求,这些成本可能转化为更高延迟、更低吞吐、更大显存占用和更高设备费用。
本项目因此探索独立小分类器:输入一段中文,直接输出风险与服务意图。实验不是先决定线上架构,而是回答一个更基础的问题:固定分类任务能否在保留足够质量的同时,显著降低推理成本。
大参数生成模型只是性能问题的背景,实际实验从一开始就限定为两个可在本机训练的小基模:Qwen3-0.6B 与 BGE-small-zh-v1.5。 这一区分可以避免把研究动机误解为“大模型微调方案”。
Qwen3-0.6B 代表小型生成模型路线。它约有 600.6M 参数。本项目增加序列分类头,并用 rank 16 LoRA 训练 4,587,520 个参数,约占总参数的 0.7638%。选择它,是为了保留较强的中文上下文建模能力,同时验证生成模型能否改造成固定分类器。
BGE-small-zh-v1.5 代表小型编码器路线。它是 4 层、隐藏维度 512 的中文文本编码器,本项目模型约有 24.0M 参数。选择它,是为了验证更小参数量和更短编码路径能否完成同一组风险与意图标签。
开篇明确的两条基础模型路线
首轮生成式 Qwen V1 的单条 p95 达到 2671.234 ms,这个结果直接推动了固定分类头与更小编码器的探索。 同机最终 Qwen V3 分类头的 p95 为 90.010 ms,BGE V4 为 5.548 ms。
独立分类器的性能动机
-
2671.234 ms
Qwen V1 生成式 JSON 路由的单条 p95。
-
90.010 ms
Qwen V3 固定分类头的单条 p95。
-
5.548 ms
BGE V4 固定分类头的单条 p95。
02. 任务定义与评测口径
任务使用 4 种风险标签和 11 种服务意图。实际训练不是覆盖全部笛卡尔积,而是映射为 13 个有效联合类别,例如 emergency_symptom、routine_appointment 和 uncertain_unknown。固定分类头一次前向即可输出 13 类 logits,再由版本化映射还原风险与意图。
联合分类把输出空间固定下来,消除了 JSON 解码失败,并让置信度、校准和逐类别错误可以直接测量。 质量指标包括联合 Macro-F1、风险 Macro-F1、意图 Macro-F1、急症召回、ECE 和 NLL。
性能评测固定在 Intel Arc 130T 上进行。单条延迟采用 20 轮预热和 200 轮测量,吞吐使用 batch=8。峰值显存来自 PyTorch XPU allocator,只代表本次进程分配的张量峰值。
训练前后的比较必须冻结验证集、测试集、标签映射和测量方法。V2、V3 与 V4 共用 220 条验证数据和 247 条固定测试数据;挑战集用于回归已知困难输入,不再视为独立盲测。
03. 两条基础模型路线的对照方式
Qwen 路线使用同一个 13 类联合分类目标。训练先完成 frozen linear probe,再用其分类头初始化 LoRA。BGE 路线同样输出 13 类 logits,但对约 24.0M 参数进行全量微调,并为编码器和随机分类头设置不同学习率。
两条路线共享标签空间、验证集、固定测试集和性能测量方法,但训练参数量与优化方式不同,因此比较的是完整工程方案,而不是只比较基模名称。 结果需要同时查看质量、错误类型、延迟、吞吐、显存和训练时间。
04. 从 V1 到 V4 的优化路径
整个迭代不是简单增加样本,而是逐轮处理上一轮暴露出的主要瓶颈。V1 先证明任务可学;V2 改变输出形式;BGE V2 验证小编码器;V3 处理数据覆盖;V4 再处理 BGE 的上下文边界。
每轮优化都由可观察问题驱动:先改生成延迟,再改分类头训练,再补类别覆盖,最后处理否定、转述和相邻意图。
五个关键实验阶段
-
V1:生成式 Qwen LoRA
使用 263 条训练数据生成严格 JSON。微调证明任务可学,但自回归输出带来 2671.234 ms 的 p95。
-
V2:Qwen 联合分类头
改为 13 类一次前向。p95 降至 93.647 ms;随机分类头 LoRA 失败后,改用 linear probe 权重初始化。
-
BGE V2:小编码器对照
首轮统一学习率的联合 F1 只有 0.093。提高随机分类头学习率并延长训练后,固定测试联合 F1 达到 0.686012。
-
V3:扩大训练覆盖
训练集从 424 条增至 2,740 条。Qwen V3 的固定测试联合 F1 达到 0.938188,挑战回归联合 F1 达到 0.738095。
-
BGE V4:边界数据与辅助损失
新增 479 条对照样本,并加入风险与意图边际损失。挑战回归联合 F1 提升到 0.899833。
V1:先证明生成式 LoRA 能学会任务
V1 使用 263 条训练数据,对 Qwen3-0.6B 进行 4 个 epoch 的 LoRA 微调。模型自回归生成 risk、intent、route 和 need_clarification 组成的 JSON。在相同的 213 条测试数据上,风险 Macro-F1 从 0.1272 提升到 0.9217,意图 Macro-F1 从 0.0970 提升到 0.7017。急症召回从 0 提升到 0.875,非法 JSON 率从 7.51% 降到 0。
V1 证明 0.6B 模型可以学习标签和输出契约,但没有解决推理成本与长尾类别。 它仍漏判 2/16 条急症,unknown Recall 为 0。生成约 39 个输出 Token,使单条 p95 达到 2671.234 ms,batch=8 吞吐只有 2.587/s。
下一轮因此不再优化 JSON 提示词,而是改变输出机制。V2 去掉系统提示和自回归解码,改为 13 类联合分类头。目标是用一次前向直接输出 logits,同时保留风险与意图映射。
V2:分类头解决延迟,但暴露训练与数据问题
V2 的训练、验证和测试数据分别为 424、220 和 247 条。训练前先跑多数类、TF-IDF 和 frozen Qwen linear probe。linear probe 的测试 Macro-F1 为 0.7213。首轮直接训练随机分类头 LoRA 只有 0.3713,说明随机头与 LoRA 主干没有形成有效配合。
第二轮先用 linear probe 权重初始化分类头,再训练 LoRA,测试 Macro-F1 达到 0.7254。加入校准与既定安全规则后,固定测试联合 F1 为 0.698347,风险 F1 为 0.855478,意图 F1 为 0.675569;挑战回归联合 F1 为 0.577211。
V2 把 p95 从 2671.234 ms 降到 93.647 ms,提升 28.52 倍,但质量门槛没有通过。 batch=8 吞吐从 2.587/s 提升到 80.502/s。结果说明固定分类头解决了主要延迟问题,但 424 条训练数据不足,挂号、复诊、导航和 unknown 等边界仍不稳定。
下一步分成两个验证方向:一是尝试更小的 BGE 编码器,确认分类任务还能否进一步提速;二是保留固定验证和测试集,为后续数据扩充建立可比较基线。
BGE V2:小编码器获得速度与意图优势
BGE 首轮把编码器和随机分类头统一设置为 2e-5 学习率。训练 112 步后仍接近随机分类,固定测试联合 F1 只有 0.093。第二轮把编码器学习率改为 5e-5、分类头学习率改为 1e-3,并增加训练步数,未校准联合 F1 提升到 0.704。
最终校准结果中,BGE V2 固定测试联合 F1 为 0.686012,风险 F1 为 0.664101,意图 F1 为 0.806377;挑战回归联合 F1 为 0.612410。单条 p95 为 7.863 ms,batch=8 吞吐为 507.755/s,训练耗时为 24.91 秒。
BGE V2 证明约 24.0M 参数的编码器可以接近 Qwen V2 的联合质量,并显著提高速度,但风险边界明显更弱。 urgent_symptom F1 只有 0.243902,routine_symptom F1 为 0。它更擅长明确服务意图,却容易依赖局部症状关键词。
下一轮不急于改变模型结构,而是先补齐训练覆盖。V3 同时重训 Qwen 与 BGE,用同一批新增数据观察:问题主要来自样本不足,还是来自模型对组合语义的建模能力。
V3:扩大数据后,两种模型出现不同结果
V3 将训练数据从 424 条扩至 2,740 条,新增 2,316 条。最小类别从 3 条提高到 154 条,新增数据中的礼貌表达控制在 9.5%,包含“挂号”的训练输入达到 157 条。220 条验证集和 247 条测试集保持不变。
Qwen V3 的固定测试联合 F1 从 0.698347 提升到 0.938188,挑战回归联合 F1 从 0.577211 提升到 0.738095。BGE V3 的固定测试联合 F1 从 0.686012 提升到 1.000000,但挑战回归只从 0.612410 变为 0.612698,增量为 0.000288。
V3 数据对 Qwen 的复杂输入确有帮助,但 BGE 的固定测试满分主要反映模板域饱和。 BGE 仍会把已经止血、影视剧情和非本人症状中的医疗关键词判为急症。继续扩充相似模板,只会让固定测试更漂亮,无法解决上下文边界。
下一轮因此只针对 BGE 做机制和数据双重调整。V4 不复制挑战集原句,而是新增成组对照 family;训练目标也不再只看 13 类联合损失,而是额外监督风险与意图边际。
BGE V4:对照数据与多任务损失改善已知边界
V4 在 2,740 条 V3 数据上增加 479 条训练样本,总量达到 3,219 条。新增 10 个 family,覆盖已止血与急症否定、虚构与引用场景、挂号与复诊、科室与导航,以及省略式 unknown。联合损失加入权重 0.4 的风险边际损失、权重 0.3 的意图边际损失和 0.05 标签平滑。
BGE V4 的挑战回归联合 F1 从 0.612698 提升到 0.899833,风险 F1 从 0.829630 提升到 0.962865,意图 F1 从 0.738344 提升到 0.951515,错误数从 5 条降到 2 条。固定测试联合 F1 从饱和的 1.000000 回落到 0.986014,仍高于 Qwen V3 的 0.938188。
V4 说明成组对照数据与边际辅助监督可以修复 BGE 的已知弱点,但当前提升仍属于回归改进。 剩余错误是术后随访被判为挂号,以及已经止住的针眼少量出血被判为急症。固定测试还有 3 条礼貌短挂号请求被判为 unknown。
下一轮不再围绕这 2 条错误继续造模板。应冻结 Qwen V3、BGE V4、阈值和统计方法,再建立 500 至 1,000 条来源独立的盲测数据。只有新盲测才能判断 V4 的改善是否能迁移到真实表达。
05. 数据与训练方法如何逐轮调整
V1 数据证明了 LoRA 可以学习标签,但训练集小类严重不足,例如 follow_up 只有 4 条、hospital_navigation 只有 3 条。V2 将数据改成 13 类联合视图,训练、验证、测试分别为 424、220 和 247 条,并增加独立挑战回归集。
V3 针对类别不足、客套词过多和“挂号”等短输入缺失进行扩充。训练集增加到 2,740 条,每类至少 154 条;新增数据中礼貌表达占 9.5%,包含“挂号”的训练输入达到 157 条。验证集和测试集逐字节保持不变,归一化重复数为 0。
V3 解决覆盖不足后,BGE 固定测试达到饱和,但挑战集几乎没有提升,这说明下一步要补上下文对照,而不是继续堆同类模板。 BGE V3 会把已经止血、影视剧情和非本人症状中的医疗关键词误判为急症。
V4 在 V3 基础上新增 479 条训练样本,总量达到 3,219 条。10 个新 family 覆盖已止血、急症否定、虚构或引用场景、挂号与复诊、科室与导航,以及省略式未知输入。
训练数据演进
-
424
V2 的 13 类联合训练样本数。
-
2,740
V3 补齐类别和输入风格后的训练样本数。
-
3,219
BGE V4 加入 479 条困难对照样本后的训练样本数。
BGE V4 的损失由 13 类联合交叉熵、风险边际损失和意图边际损失组成。两个辅助项权重分别为 0.4 和 0.3,联合损失使用 0.05 标签平滑。模型输出和推理接口保持不变。
06. 基线、训练与复现实验
V2 训练先跑多数类、TF-IDF、冻结 Qwen linear probe 和随机头 LoRA。冻结 linear probe 的测试 Macro-F1 为 0.7213,随机分类头 LoRA 只有 0.3713。第二轮用 linear probe 权重初始化分类头,LoRA 达到 0.7254,证明初始化方式比直接增加训练步骤更关键。
基准测试必须先于正式训练,并保留相同数据、配置、checkpoint、评测 JSON 和性能 JSON。 V3 与 V4 的复现命令如下,代码块在中英文正文中保持一致。
# Train and evaluate the final Qwen V3 and BGE V4 classifiers
.\.venv-xpu\Scripts\python.exe -m med_router.v2.expand_training --config configs\v3\data.yaml
.\.venv-xpu\Scripts\python.exe -m med_router.v2.train --config configs\v3\qwen_linear_probe.yaml
.\.venv-xpu\Scripts\python.exe -m med_router.v2.train --config configs\v3\qwen_lora.yaml
.\.venv-xpu\Scripts\python.exe -m med_router.v2.evaluate --config configs\v3\qwen_eval.yaml
.\.venv-xpu\Scripts\python.exe -m med_router.v2.benchmark --config configs\v3\qwen_benchmark.yaml
.\.venv-xpu\Scripts\python.exe -m med_router.v2.expand_training --config configs\v4\bge_data.yaml
.\.venv-xpu\Scripts\python.exe -m med_router.bge.train --config configs\v4\bge_train.yaml
.\.venv-xpu\Scripts\python.exe -m med_router.bge.evaluate --config configs\v4\bge_eval.yaml
.\.venv-xpu\Scripts\python.exe -m med_router.bge.benchmark --config configs\v4\bge_benchmark.yaml如果 PyTorch 回退到 CPU,或没有加载 XPU 构建,质量评测仍可运行,但性能数字不能与本文直接比较。重新训练后也应重新生成哈希与报告,不能沿用旧结论。
07. 最终质量结果
Qwen V3 在 247 条固定测试集上的联合 F1 为 0.938188,风险 F1 为 0.975096,意图 F1 为 0.936507。在挑战回归集上,联合 F1 为 0.738095,风险 F1 为 0.952210,意图 F1 为 0.694444。
BGE V4 在固定测试集上的联合 F1 为 0.986014,风险 F1 为 0.983324,意图 F1 为 0.983471。在挑战回归集上,联合 F1 为 0.899833,风险 F1 为 0.962865,意图 F1 为 0.951515。
当前可确认的结果是:BGE V4 在固定测试与已知挑战回归上都高于 Qwen V3,但这些集合已经参与优化方向设计,不能证明真实输入上的绝对优势。 两个模型的急症召回在挑战回归集上均为 1.0。
最终联合 Macro-F1
-
0.938188
Qwen V3 固定测试集。
-
0.986014
BGE V4 固定测试集。
-
0.899833
BGE V4 挑战回归集;该集合不是独立盲测。
BGE V4 的挑战回归错误从 V3 的 5 条降至 2 条。剩余错误是把术后随访判为挂号,以及把已经止住的针眼少量出血判为急症。固定测试集还有 3 条礼貌短挂号请求被判为 unknown。
08. 最终性能与训练成本
最终复测中,BGE V4 的单条 p95 为 5.548 ms,batch=8 吞吐为 578.603 条每秒,峰值分配显存为 47.37 MiB。Qwen V3 的对应结果为 90.010 ms、75.375 条每秒和 1,169.22 MiB。
在本机相同测量口径下,BGE V4 的 p95 约为 Qwen V3 的 1/16.22,吞吐约为 7.68 倍,峰值分配显存约为 1/24.68。 这些数字说明独立小编码器具备明显的工程成本优势。
最终对比结果汇总
| 模型 | 训练方式 | 固定测试联合 F1 | 挑战回归联合 F1 | 单条 p95 | batch=8 吞吐 | 峰值分配显存 | 训练耗时 |
|---|---|---|---|---|---|---|---|
| Qwen V3 | LoRA(4,587,520 个可训练参数) | 0.938188 | 0.738095 | 90.010 ms | 75.375/s | 1,169.22 MiB | 714.05 s(126.91 + 587.14) |
| BGE V4 | 全量微调(约 24.0M 参数) | 0.986014 | 0.899833 | 5.548 ms | 578.603/s | 47.37 MiB | 53.62 s |
单条推理 p95 的直接对比为:Qwen V1 生成式 2671.234 ms、Qwen V3 分类式 90.010 ms、BGE V4 分类式 5.548 ms。
训练成本同样存在差异。Qwen V3 的 linear probe 用时 126.91 秒,LoRA 用时 587.14 秒,合计约 11.9 分钟。BGE V4 全量微调用时 53.62 秒,最佳 checkpoint 位于 epoch 6。
BGE V3 与 V4 使用相同模型结构,因此 8.338 ms 与 5.548 ms 的差异应视为测量波动,不能归因于训练数据让模型结构变快。性能结果也不能直接外推到不同服务器、CPU 或移动设备。
09. 结果边界与下一步验证
这轮探索已经回答两个工程问题。第一,生成式路由可以改成固定分类头,显著减少延迟。第二,在当前标签与数据上,约 24.0M 参数的 BGE V4 可以取得高于 Qwen V3 的回归质量,同时保持更低的训练和推理成本。
尚未回答的是独立泛化。V3 固定测试集和 round2 挑战集都影响过后续数据设计,因此它们只能用于防回归。训练数据仍以合成为主,风险标签没有完成临床验证。
最终结果支持继续验证 BGE V4,但不支持从当前分数直接推荐单模型、双模型、级联或规则组合。 下一步应冻结 Qwen V3、BGE V4、阈值和统计方法,再建设 500 至 1,000 条来源独立的盲测数据。
新盲测需要覆盖真实短句、错别字、方言、语音转写、否定、转述、虚构场景和复合请求。症状风险标签需要由有资质人员复核,并按错误代价分别查看漏判、过度升级和意图混淆。
REFERENCES