[大模型微调实战] 16k 数据撬动 300 亿大模型!我用 Qwen3-VL 打造了一位“顶尖放射科医生” - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
okoklll
V2EX    分享创造

[大模型微调实战] 16k 数据撬动 300 亿大模型!我用 Qwen3-VL 打造了一位“顶尖放射科医生”

  •  
  •   okoklll 10 天前 1009 次点击

    这是一个医疗领域的多模态大模型微调案例,希望对各位开发者和爱好者有所帮助。

    简介

    当前通用多模态视觉语言模型在医疗影像场景中存在显著技术瓶颈:高分辨率医学影像(如 CT 、MR )的细粒度特征提取能力不足,且模型推理时显存占用高、计算效率低,难以支撑临床实时分析与大规模部署需求。

    患者提问:“请使用中文详细描述这张图像并给出你的诊断结果。”

    img

    这是微调前模型的回答。虽然能够识别出基本病变,但其分析存在明显不足,描述过于简略,仅关注单一病灶而忽略了图像中实际存在的双肺多发性结节,且诊断结论过于武断,直接定性为"良性肿瘤",缺乏严谨的鉴别诊断思路,临床参考价值有限。

    img

    这是微调后模型的回答。它成功化身为“严谨的放射科医生”,不仅准确定位双肺病灶,系统分析肺部结构、心脏大血管和骨骼关系,更能从病灶特征、位置分布和临床意义多个维度进行专业解读,提供完整的鉴别诊断思路,其描述精准、逻辑严密、术语规范,已达到辅助医生进行临床决策的实用水平。

    通过以上对比可以直观地看到,经过高质量数据微调后的模型,成功地从一位“门外汉”进化为了可靠的“AI 放射科医生”。

    一、项目背景:打破医疗 AI 的“不可能三角”

    当前,通用视觉大模型在医疗影像场景中存在三大瓶颈:

    细节捕捉弱:难以看懂高分辨率( CT/MR )影像中的微小病灶

    显存占用高:动辄数十 GB 的显存需求,边缘设备跑不动,难以临床部署;

    专业表述差:生成内容缺乏临床术语,可信度低,难以支撑临床实时分析需求。

    二、方案设计:稀疏激活 + 高效微调

    在医疗场景下,我们面临着“既要马儿跑,又要马儿少吃草”的悖论:

    要精度: 必须看懂高分辨率 CT/MR ,参数量不能小( 30B 级别)

    要成本: 医院边缘设备显存有限,跑不动庞然大物

    我们选择了Qwen3-VL-30B-A3B-Instruct,正是因为它采用了 “稀疏激活( Active 3B )” 架构。它拥有 300 亿参数的知识储备,但推理时仅激活 30 亿参数这为低成本落地埋下了伏笔。

    配置参数 配置项 说明
    模型 Qwen3-VL-30B-A3B-Instruct 稀疏激活架构,仅激活 3B 参数,支持高分辨率动态切换,极大节约计算资源
    数据集 MedTrinity-25M (16k 样本子集) 选取的数据集是 MedTrinity-25M 子集中的其中一个( 16163 张图片),MedTrinity-25M 是当前规模最大的公开医学影像-文本对数据集,涵盖超过 2500 万张图像,涉及 CT 、MR 、X-Ray 等多种模态,并为 65 多种疾病提供了多层次的注释
    GPU H800 * 4 (推荐) 模型规模较大,建议配置足够显存以确保稳定高效训练
    微调方法 LoRA 显著降低计算与存储成本,实现大模型的高效轻量化微调

    三、训练实战:从数据到可对话的医疗专家

    1 、数据加工:把“医学教材”喂给 AI

    高质量、格式规范的数据集是成功的关键。我们通过以下流程将原始医学数据转化为模型可理解的“教材”:

    下载数据:从 MedTrinity-25M 数据集中精选 1.6 万条高质量影像-文本对

    格式转换:使用定制 Python 脚本,将原始数据转换为LLaMA-Factory Online支持的 ShareGPT 多模态对话格式

    质量验证:通过随机抽样与基线模型测试验证数据有效性。

    核心代码详解:我们提供了完整的数据格式转换脚本,将原始 Parquet 数据转换为模型可训练的格式。

    #多模态数据格式转换代码 import os import json import random from tqdm import tqdm import datasets def save_images_and_json(ds, ratio=0.1, output_dir="mllm_data"): """ 保存数据集中的图像,并且构建多模态训练集和验证集。 参数: ds: 数据集对象,包含图像和描述。 ratio: 验证集比例,默认为 0.1 。 output_dir: 输出目录,默认为 "mllm_data"。 """ # 创建输出目录 os.makedirs(output_dir, exist_ok=True) all_train_data = [] # 多模态训练数据 all_val_data = [] # 多模态验证数据 total_samples = len(ds) val_index = set(random.sample(range(total_samples), int(ratio * total_samples))) # 遍历数据集中的每个项目 for idx, item in tqdm(enumerate(ds), total=total_samples, desc="Processing"): img_path = os.path.join(output_dir, f"{item['id']}.jpg") image = item["image"] # 保存图像 image.save(img_path) sample = { "messages": [ { "role": "user", "content": "<image>图片中的诊断结果是怎样?" }, { "role": "assistant", "content": item["caption"] # 从数据集中获取的描述 } ], "images": [img_path] # 图像文件路径 } if idx in val_index: all_val_data.append(sample) else: all_train_data.append(sample) # 将数据保存到 JSON 文件 train_json_path = os.path.join(output_dir, "mllm_train_data.json") val_json_path = os.path.join(output_dir, "mllm_val_data.json") with open(train_json_path, "w", encoding="utf-8") as f: json.dump(all_train_data, f, ensure_ascii=False, indent=2) with open(val_json_path, "w", encoding="utf-8") as f: json.dump(all_val_data, f, ensure_ascii=False, indent=2) if __name__ == "__main__": # 加载数据集 ds = datasets.load_dataset("parquet", data_files="../dataset/data_sft/train-00000-of-00010.parquet")["train"] # 保存图像并构建多模态训练/验证集 save_images_and_json( ds, ratio=0.2, output_dir="/workspace/user-data/codelab/Qwen3-VL/dataset/mllm_data" ) 

    转换后的数据示例如下:

    [ { "messages": [ { "role": "user", "content": "<image>图片中的诊断结果是怎样?" }, { "role": "assistant", "content": "这是一张非增强脑部计算机断层扫描( CT )图像,图中未见任何医疗设备。位于图像中央的兴趣区域可见密度改变,提示脑内出血。该异常区域与周围脑组织分界清晰,可能为脑实质内血肿或出血。其位置及表现可能与邻近脑组织存在关联,进而产生占位效应或导致颅内压升高。" } ], "images": [ "/workspace/user-data/codelab/Qwen3-VL/dataset/mllm_data/8031efe0-1b5c-11ef-8929-000066532cad.jpg" ] }, { "messages": [ { "role": "user", "content": "<image>图片中的诊断结果是怎样?" }, { "role": "assistant", "content": "这是一张脑部非增强计算机断层扫描( CT )图像,显示双侧大脑半球,图中无医疗器械。感兴趣区域位于脑中央偏下方,约占图像面积的 1.1%,表现异常,提示可能存在病变:其密度或纹理改变符合颅内出血特征。该区域与周围脑结构紧邻,可能对邻近组织产生压迫,或受邻近组织影响,提示病变可能正在扩展,并可能影响周边组织功能。" } ], "images": [ "/workspace/user-data/codelab/Qwen3-VL/dataset/mllm_data/803201d1-1b5c-11ef-bba0-000066532cad.jpg" ] }, ] 

    2 、模型训练:找到医疗影像的“学习密码”

    训练一个专业模型,不仅是“跑起来”,更要“学得好”。参数调优就是寻找最佳“学习方案”的过程。我们通过严谨的对比实验,揭示了影响医疗影像学习效果的关键因素。

    ( 1 ) DeepSpeed Stage 选择是性能关键

    在微调 30B 级别大模型时,很多人的第一反应是无脑开 DeepSpeed Stage 3 以节省显存。但在医疗影像这种需要极高精度的任务中,我们通过实战验证了一个残酷的真相:

    误区( DeepSpeed Stage 3 ): 虽然显存占用低,但在医疗细粒度特征上,Loss 下降缓慢。原因在于 Stage 3 的“参数延迟+梯度噪声”机制,干扰了模型对微小病灶的学习

    正解( DeepSpeed Stage 2 ): 虽然显存占用稍高,但 loss 曲线如丝般顺滑,收敛更彻底

    独家心法:在LLaMA-Factory Online配置时,若显存允许(如使用 H800 ),请果断选择 Stage 2 。如果必须用 Stage 3 ,请务必配合“放大 Global Batch Size+拉长 Warmup”的组合拳来弥补性能损失。

    ( 2 )参数配置对比实验与分析

    为验证上述发现,在任务模式下,我们对模型进行了两组微调实验(参数一和参数二),以评估不同配置的效果。两组实验的变量仅为 per_device_train_batch_size ( 32 ,4 )和 DeepSpeed ( 3 ,2 )参数,其他条件完全相同。具体参数差异如下表所示:

    配置参数 参数说明 参数一 参数二
    基础配置
    model 训练用的基模型 Qwen3-VL-30B-A3B-Instruct Qwen3-VL-30B-A3B-Instruct
    dataset 训练使用的数据集名称 mllm_train_data mllm_train_data
    stage 训练方式 sft sft
    finetuning_type 微调方法 lora lora
    进阶配置
    LR Scheduling Type 动态调整学习率的方式 cosine cosine
    Max Gradient Norm 梯度裁剪的最大范数,用于防止梯度爆炸1.0 1.0
    训练配置
    Learning Rate 学习率 5e-05 5e-05
    Epochs 训练轮数 2 2
    per_device_train_batch_size 单 GPU 批处理大小 32 4
    Gradient Accumulation 梯度累计,将一个完整批次的梯度计算拆分为多个小批次,逐步累积梯度,最后统一更新模型参数 8 8
    Save steps 训练过程中每隔多少个训练步保存一次模型 200 200
    Warmup Ratio 将学习率从零增加到初始值的训练步数比例 0 0
    Chat Template 基模型的对话模版,训练和推理时构造 prompt 的模版 qwen3 qwen3
    效率与性能配置
    Mixed Precision Train 混合精度训练,模型在训练或推理时所使用的数据精度格式,如 FP32 、FP16 或 BF16 bf16 bf16
    分布式配置
    DeepSpeed Deepspeed Stage 是 DeepSpeed 中 ZeRO ( Zero Redundancy Optimizer )优化技术的阶段参数,其范围是 none 、2 、3 。参数越大,意味着模型状态的分片程度越高,每个 GPU 的内存占用越少,但同时通信开销也可能越大 3 2
    数据参数配置
    Max Sample Size 每个数据集的最大样本数:设置后,每个数据集的样本数将被截断至指定的 max_samples 100000 100000
    Cutoff Length 输入的最大 token 数,超过该长度会被截断 2048 2048
    Preprocess Workers 预处理时使用的进程数量 32 32
    日志配置
    Logging Steps 日志打印步数 5 5
    LoRA 配置
    LoRARank LoRA 微调的本征维数 r ,r 越大可训练的参数越多 8 8
    LoRAScalling Factor LoRA 缩放系数。一般情况下为 lora_rank * 2 16 16
    Random dropout LoRA 微调中的 dropout 率 0 0
    LoRAModules Lora 作用模块 all all

    通过任务模式完成两组参数配置的模型微调后,从 loss 对比结果来看,相同硬件与数据集条件下,deepseed 3 (参数一)方案训练速度更快,但微调阶段 loss 显著上升; deepseed 2 (参数二)方案虽训练速度略有下降,却能更有效地压低 loss 。具体来看:

    ● deepseed 3 训练速度的提升,核心得益于 “小块通讯 + 微批次自动放大” 带来的带宽优化;

    ● deepseed 3 微调 loss 上涨的本质,是 “参数延迟 + 梯度噪声” 导致模型收敛效果变差;

    选型建议:若显存充足,优先选择 deepseed 2 方案以追求更优指标;若显存不足需使用 deepseed 3 ,则需同步通过放大 global batch 、拉长 warmup 时长、降低学习率( lr )的方式弥补收敛性能。

    通过反复实验,我们总结出了一套适用于 Qwen3-VL 医疗微调的参数心法

    LR Scheduler (学习率调度): 放弃 Linear !在多模态图文对齐任务中,Linear 衰减表现平平。请选择 Cosine + Warmup ,它能更好地适配视觉特征的学习节奏

    Epoch (训练轮数):在 16k 数据场景下,3 个 Epoch 是性能拐点;第 4 个 Epoch 起训练 Loss 仍降,但验证指标不再上升,属于典型过拟合; 5k 小数据场景下可拉到 6~8Epoch

    LoRARank:医疗影像细节极多(如微小结节、毛刺征),低 Rank (如 8 以下)表达能力不足。Rank 32 是效果与成本的性价比拐点

    Alpha 值: 死磕公式 Alpha = Rank×2 ,稳定性最佳

    dropout:数据量 ≤ 10k 时,设置 dropout=0.05 可有效防过拟合;数据 > 10k:可直接设为 0

    3 、效果验证:从“业余”到“专业”的飞跃

    经过精心的微调,模型的性能实现了质的飞跃。我们通过量化指标和定性分析,全方位评估其提升效果。

    ( 1 )指标对比:数十倍至上千倍的提升

    下面的数据清晰地展示了模型在微调前后的巨大变化。其中,参数二( DeepSpeed Z2 方案) 在各项文本生成质量指标上达到了最优水平。

    评估指标 微调前(原生模型) 参数一微调后 (Z3 方案) 参数二微调后(Z2 方案)
    BLEU-4 0.806 27.653 92.375
    ROUGE-1 2.778 38.069 96.114
    ROUGE-2 0.006 16.363 94.036
    ROUGE-L 2.013 20.695 94.286

    指标解读

    BLEU-4衡量生成文本与专业参考答案在词组和表达上的匹配度

    ROUGE-1/2/L综合评估生成内容的关键词覆盖、短语搭配和句法连贯性

    结论一目了然:采用Z2 方案微调的模型(参数二),其生成质量远超原生模型和 Z3 方案,在专业术语、句式结构和临床逻辑上都与标准医学描述高度一致。

    ( 2 )生成质量:从“无法使用”到“专业优秀”

    微调前(原生模型):各项指标极低,生成内容与参考答案关联性微弱,逻辑混乱,完全无法满足专业场景需求

    微调后(参数二模型)

    BLEU-4高达 92.37 ,意味着模型能精准复现医学报告中的专业词汇与表达

    ROUGE系列指标均超过 94 ,代表其在关键词捕捉、专业短语运用和长篇报告的连贯性上表现出色

    ○ 生成文本的质量已达到优秀级别,具备临床应用的潜力

    ( 3 )效率提升:速度与精度的双重胜利

    除了生成质量,推理效率也得到显著优化。

    评估指标 微调前(原生模型) 参数一微调后 (Z3 方案) 参数二微调后(Z2 方案)
    predict_samples_per_second 0.773 0.057 0.194
    predict_steps_per_second 0.048 0.002 0.048
    predict_runtime 4179.834 56431.560 16668.369

    微调不仅解决了原生模型生成质量“不可用”的核心问题,更在效率上实现了超越。最终得到的模型在专业性准确性响应速度上取得了完美平衡,可立即投入医学影像报告生成、辅助诊断等严肃多模态场景。

    4 、实战对话:真正的“AI 放射科医生”

    模型性能的最终检验标准在于实战。我们对比了参数一( Z3 方案)参数二( Z2 方案)微调后的模型对同一张胸部 CT 影像的分析,结果显示两者均达到专业水准,但在分析的全面性细致程度诊断深度上存在显著差异。

    img

    img

    通过对比分析,我们验证了一个重要结论,参数二( Z2 方案) 在以下方面表现显著更优:

    观察敏锐度:能够发现图像中的多个病灶,避免漏诊

    分析系统性:提供从解剖结构到病变特征的完整分析框架

    诊断严谨性:基于医学证据进行推理,给出合理的鉴别诊断

    临床实用性:回答具有直接临床参考价值

    这一结果与我们之前的实验数据高度吻合Z3 方案虽然在训练速度上稍慢,但能够学习到更丰富的医学知识结构和诊断逻辑,最终生成的影像报告更接近资深放射科医生的专业水准。

    还有一些情感陪伴、数字分身、教育、客服等场景的案例,看看大家对哪个感兴趣,可以后续再分享,也欢迎大家到LLaMA-Factory Online复现这个项目。

    1 条回复
    lloovve
        1
    lloovve  
       10 天前 via iPhone
    个人感觉这个场景,一个是数据量不够大,二是 30b 模型太小,覆盖的知识不足。要达到实用化,必须解决这两个问题,足够的数据量,台依托超大模型。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3478 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 05:05 PVG 13:05 LAX 21:05 JFK 00:05
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86