YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
CCL2026 中文电子病历疾病与手术ICD自动编码 — 推理提交包
本文件夹为自包含的推理系统:给定一个电子病历 xlsx,输出每条病历的 4 个 ICD 编码字段。 模型与代码已全部就位,无需联网、无需额外下载即可运行。
- 方案:
Qwen3.5-4B(base,≤7B 合规)+ LoRA 微调(V2 重排版checkpoint-400),vLLM 推理。 - 与 A 榜最佳一致:推理链路 = base+LoRA + 手工 prompt +
postprocess_reorder还原提交格式,与 A 榜实测 0.8850 的result_ft_reorder_ckpt400.txt完全相同。
一、目录结构
tijiao/
├── README.md # 本文件(使用说明)
├── 环境安装说明.md # 环境/依赖安装(从零 or 用vLLM镜像)
├── requirements.txt # 依赖版本清单(实测可复现)
├── run_infer.sh # ★一键推理脚本
│
├── baseline/ # 代码
│ ├── infer.py # 推理入口(读xlsx → 名称→编码 → 后处理 → result.txt)
│ ├── run_baseline.py # 共享内核(知识库/匹配器/DX2OP/格式; import时加载知识库)
│ └── eval_mtotal.py # 离线评测(官方M_total, 有金标时用, 可选)
│
├── icd_knowledge_base/ # ICD知识库(必须在 baseline 上一级目录)
│ ├── task_candidates.json # 18主诊断 + 16主手术 封闭候选集
│ ├── icd10_diseases.json # ICD-10 疾病库(名称→编码)
│ ├── icd9cm3_procedures.json # ICD-9-CM3 手术库(名称→编码)
│ └── code2name.json / name2codes.json / metadata.json
│
├── train_data/ # 推理用映射(由训练集统计得到)
│ ├── name2code_map.json # 训练集金标准 名称→编码(三级映射第1级)
│ └── dx2op_train.json # 主诊断→主手术 白名单先验
│
└── model/
├── Qwen3.5-4B/ # base 模型(8.8G)
└── lora/checkpoint-400/ # LoRA 适配器(adapter_config + adapter_model, 259M)
⚠️ 路径约束:
run_baseline.py在 import 时按"自身上一级目录 / icd_knowledge_base"定位知识库。 因此baseline/与icd_knowledge_base/必须保持上述相对位置,不要单独移动 baseline 目录。
二、快速运行
cd tijiao
bash run_infer.sh <输入xlsx> <输出txt>
- 不带参数时:默认输入
../o_data/B榜.xlsx,输出./result.txt。 - 例(对 B 榜):
bash run_infer.sh /path/to/B榜.xlsx ./result_B.txt - Docker 场景(读
/input、写/output):bash run_infer.sh /input/B_test.xlsx /output/result.txt
运行约 2–3 分钟(含 vLLM 冷启动 + torch.compile;400 条实际推理仅 ~80s)。
完成后打印 完成: N 条 -> <输出> (非法行 0)。
显存需求:4B + LoRA,bf16,
gpu_memory_utilization=0.85,max_model_len=8192。 单卡 ≥16GB 即可(实测 NVIDIA vGPU-32GB,峰值约 12GB)。
三、输入 / 输出格式
输入:电子病历 xlsx。脚本会自动在所有 sheet 中寻找含 主诉 或 病案标识 列的那个 sheet
(B 榜 xlsx 真数据在 Sheet1,默认 Sheet2 是空壳,已自动处理)。使用的病历字段:
主诉, 现病史, 既往史, 入院诊断, 诊疗经过, 出院情况, 出院医嘱, 术前诊断, 术中诊断, 手术经过
输出:纯文本 result.txt,每行一条病历、按输入行序对齐,4 字段用 | 分隔,
其他诊断/手术内部用 ; 分隔(官方格式):
主诊断码|其他诊断码1;其他诊断码2;…|主手术码|其他手术码1;其他手术码2
- 主诊断、主手术有且仅 1 个;其他手术最多 2 个。
- 例:
O34.201|O82.000;Z37.000x001;Z35.401|74.1x01|65.2901
四、方案要点(为何这样设计)
- 名称版微调:模型输出 ICD 中文名称(非编码串),名称有语义、易学;再用映射还原编码 (名称↔编码 100% 可逆)。
- V2 重排:模型按
主诊|主术|其他诊|其他术输出(主码相邻,强化 80% 权重主码学习);postprocess_reorder()解析后还原为提交序主诊|其他诊|主术|其他术。 - 名称→编码三级映射:
NAME2CODE(训练集金标准,优先)→ 知识库精确 → LCS 模糊兜底。 - 主码兜底:
coerce把主诊/主术吸附到 18/16 封闭候选集(保证合法);DX2OP 白名单信任模型、仅在明显错时纠正(实测后处理无损 M=1.0)。
五、离线评测(可选)
有金标时(如自留验证集),用官方指标核对:
python3 baseline/eval_mtotal.py 预测.txt 金标.txt
# 输出: 主诊Acc / 其他诊F1 / 主术Acc / 其他术F1 / M_total
# 评分: M = 0.4·Acc(主诊) + 0.1·F1(其他诊) + 0.4·Acc(主术) + 0.1·F1(其他术)
六、注意事项
- 必须带
--reorder(run_infer.sh 已内置):本 LoRA 是重排版,漏了它会导致主术/其他诊错位,主码全错。 - base+LoRA,勿用 merge 模型:merge 版与 base+LoRA 推理有约 32 行差异,本包用 base+LoRA。
- 环境/依赖见《环境安装说明.md》;若 vLLM 启动报
ninja/nvcc缺失,见该文档"常见问题"。
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support