项目概述

本项目基于 DeepSeek-Coder-7B-Base-v1.5 模型,使用华佗医疗问答数据集进行增量预训练,旨在提升模型在医疗领域的问答能力。采用 LoRA (Low-Rank Adaptation) 技术进行参数高效微调。

技术栈

  • 基础模型: DeepSeek-Coder-7B-Base-v1.5 (6.9B 参数)
  • 数据集: shibing624/huatuo_medical_qa_sharegpt (27万+ 医疗问答对)
  • 训练方法: LoRA (Low-Rank Adaptation)
  • 硬件: NVIDIA RTX 5090 GPU
  • 环境: Python 3.11.5, PyTorch nightly (CUDA 12.8)

时间线记录

第一阶段:环境准备与模型选择

问题发现

用户希望将基础模型从 Qwen2.5-0.5B 更换为 DeepSeek 7B,并使用华佗医疗数据集进行增量预训练。

解决方案

  1. 模型选择: 选择 DeepSeek-Coder-7B-Base-v1.5 作为基础模型

    • 优势:更大的模型容量,更强的代码理解能力
    • 挑战:需要更多计算资源和存储空间
  2. 数据集选择: 使用 shibing624/huatuo_medical_qa_sharegpt

    • 格式:ShareGPT 对话格式
    • 内容:医疗问答数据
    • 规模:27万+ 对话对

新增工具

创建了 run_pt_deepseek_huatuo.sh 训练脚本,配置了基本的训练参数。

第二阶段:数据处理与格式转换

问题发现

华佗数据集采用 ShareGPT 格式,包含 conversations 字段,而原始训练脚本期望 text 字段。

解决方案

  1. 数据格式分析:

    # 原始格式
    {
      "conversations": [
        {"from": "human", "value": "问题"},
        {"from": "gpt", "value": "回答"}
      ]
    }
  2. 格式转换函数:

    def convert_conversations_to_text(examples):
        texts = []
        for conversations in examples['conversations']:
            text = ""
            for conv in conversations:
                if conv['from'] == 'human':
                    text += f"问:{conv['value']}\n"
                elif conv['from'] == 'gpt':
                    text += f"答:{conv['value']}\n"
            text += "\n" + "="*50 + "\n\n"
            texts.append(text)
        return {"text": texts}

新增工具

修改了 pretraining.py,在数据处理部分添加了华佗数据集的自动检测和转换逻辑。

第三阶段:网络访问优化

问题发现

在中国大陆访问 Hugging Face 速度较慢,影响模型和数据集下载。

解决方案

  1. 镜像源配置:

    export HF_ENDPOINT=https://hf-mirror.com
  2. 代理环境变量清除:

    unset http_proxy
    unset https_proxy
    unset all_proxy
    unset HTTP_PROXY
    unset HTTPS_PROXY
    unset ALL_PROXY
  3. 缓存目录配置:

    export HF_HOME=/root/autodl-tmp/huggingface
    export TRANSFORMERS_CACHE=/root/autodl-tmp/huggingface
    export HF_DATASETS_CACHE=/root/autodl-tmp/huggingface/datasets

新增工具

创建了 run_pt_deepseek_huatuo_data_disk.sh 脚本,专门配置了数据盘和镜像源。

第四阶段:训练配置与执行

训练参数配置

python pretraining.py \
    --model_name_or_path deepseek-ai/deepseek-coder-7b-base-v1.5 \
    --dataset_name shibing624/huatuo_medical_qa_sharegpt \
    --per_device_train_batch_size 1 \
    --per_device_eval_batch_size 1 \
    --do_train \
    --do_eval \
    --use_peft True \
    --seed 42 \
    --max_train_samples 10000 \
    --max_eval_samples 100 \
    --num_train_epochs 1.0 \
    --learning_rate 2e-4 \
    --warmup_ratio 0.05 \
    --weight_decay 0.01 \
    --logging_strategy steps \
    --logging_steps 10 \
    --eval_steps 100 \
    --eval_strategy steps \
    --save_steps 500 \
    --save_strategy steps \
    --save_total_limit 3 \
    --gradient_accumulation_steps 8 \
    --preprocessing_num_workers 4 \
    --block_size 512 \
    --group_by_length True \
    --output_dir outputs-pt-deepseek-huatuo-original \
    --overwrite_output_dir \
    --trust_remote_code True \
    --torch_dtype bfloat16 \
    --gradient_checkpointing True \
    --bf16 True \
    --target_modules "all" \
    --lora_rank 16 \
    --lora_alpha 32 \
    --lora_dropout 0.05

关键参数说明

  • LoRA 配置: rank=16, alpha=32, dropout=0.05
  • 训练样本: 限制为 10,000 个样本(用于快速验证)
  • 批次大小: 1(受 GPU 内存限制)
  • 梯度累积: 8 步(有效批次大小 = 8)
  • 学习率: 2e-4(适中的学习率)

第五阶段:训练过程监控

训练指标

  • 训练时长: 22分21秒
  • 训练样本数: 6,781个
  • 训练损失: 从 1.7279 下降到 1.4042
  • 训练速度: 5.056 samples/second

评估指标

  • 评估损失: 1.3124
  • 评估准确率: 67.51%
  • 困惑度: 3.7152
  • 评估样本数: 64个

模型保存

  • LoRA 适配器: adapter_model.safetensors (149MB)
  • 配置文件: adapter_config.json
  • 分词器: 保存了训练时使用的分词器配置

第六阶段:模型验证与测试

验证方法

创建了多个测试脚本来验证训练效果:

  1. 简单测试脚本 (simple_test.py):

    • 加载训练好的模型
    • 测试预设的医疗问题
    • 验证回答质量
  2. 交互式测试脚本 (interactive_test.py):

    • 支持用户输入问题
    • 实时生成回答
    • 便于调试和体验
  3. 模型对比验证脚本 (verify_model.py):

    • 对比基础模型和训练后模型
    • 验证 LoRA 适配器是否生效
    • 显示模型参数信息

测试结果对比

基础模型回答:

收缩压是指心脏收缩时,动脉血管的压强,用一个血压计测量的数值;舒张压是指心脏

训练后模型回答:

高血压,也被称为高血压病,是一种长期血压持续升高的情况。正常人的血压通常在120/80毫米汞柱以下,但当血压持续超过这个范围时,就可能会导致高血压。高血压的症状可能包括头痛、头晕、心悸、疲劳、失眠、视力模糊等。

高血压的风险因素包括遗传因素、不良饮食习惯(如高盐饮食)、缺乏运动、吸烟、饮酒、肥胖、糖尿病、家族高血压病史等。

技术原理详解

LoRA (Low-Rank Adaptation) 原理

LoRA 是一种参数高效微调方法,通过低秩分解来减少可训练参数数量:

  1. 原始权重矩阵: W ∈ R^(d×k)
  2. LoRA 分解: W = W₀ + ΔW,其中 ΔW = BA
  3. 低秩矩阵: A ∈ R^(r×k), B ∈ R^(d×r),其中 r << min(d,k)

优势

  • 参数效率: 只训练 r×(d+k) 个参数,而不是 d×k 个
  • 存储效率: 只需要保存 LoRA 适配器,而不是完整模型
  • 模块化: 可以为不同任务训练不同的适配器

配置参数

  • rank (r): 16 - 低秩分解的秩,控制适配器容量
  • alpha: 32 - 缩放因子,控制适配器影响强度
  • dropout: 0.05 - 防止过拟合
  • target_modules: "all" - 对所有线性层应用 LoRA

数据处理流程

  1. 原始数据加载: 从 Hugging Face Hub 加载华佗数据集
  2. 格式检测: 自动检测 conversations 字段
  3. 格式转换: 将对话格式转换为文本格式
  4. 样本限制: 限制训练和评估样本数量
  5. 分词处理: 使用模型分词器处理文本
  6. 数据分组: 按 block_size 分组,添加 labels

训练策略

  1. 混合精度训练: 使用 bfloat16 减少内存使用
  2. 梯度检查点: 启用梯度检查点节省内存
  3. 梯度累积: 8 步累积,模拟更大批次
  4. 学习率调度: 线性 warmup 和衰减
  5. 正则化: 权重衰减防止过拟合

项目文件结构

MedicalGPT/
├── pretraining.py                    # 主训练脚本(已修改支持华佗数据集)
├── run_pt_deepseek_huatuo.sh         # 基础训练脚本
├── run_pt_deepseek_huatuo_data_disk.sh # 数据盘训练脚本
├── simple_test.py                    # 简单测试脚本
├── interactive_test.py               # 交互式测试脚本
├── verify_model.py                   # 模型验证脚本
└── outputs-pt-deepseek-huatuo-original/ # 训练输出目录
    ├── adapter_model.safetensors     # LoRA 适配器权重
    ├── adapter_config.json           # LoRA 配置
    ├── tokenizer.json                # 分词器配置
    └── train_results.json            # 训练结果

经验总结

成功因素

  1. 正确的数据处理: 自动检测和转换华佗数据集格式
  2. 网络优化: 使用国内镜像源加速下载
  3. 资源管理: 合理配置缓存目录和磁盘空间
  4. 参数调优: 适当的 LoRA 配置和训练参数

注意事项

  1. 内存管理: 7B 模型需要大量 GPU 内存,需要合理配置批次大小
  2. 网络稳定性: 模型下载可能中断,需要配置断点续传
  3. 数据质量: 确保数据格式正确,避免训练错误
  4. 验证重要性: 必须验证训练后的模型是否真正使用了 LoRA 适配器

改进方向

  1. 增加训练数据: 使用完整的 27 万样本进行训练
  2. 超参数调优: 尝试不同的 LoRA 配置和学习率
  3. 评估指标: 添加更多医疗领域的评估指标
  4. 模型部署: 考虑模型量化和部署优化

结论

本项目成功实现了基于 DeepSeek 7B 和华佗医疗数据集的增量预训练。通过 LoRA 技术,在保持基础模型不变的情况下,仅训练了 37M 参数就显著提升了模型在医疗问答方面的能力。训练后的模型在医疗问题回答上更加专业和详细,验证了增量预训练的有效性。

整个项目从环境配置、数据处理、模型训练到结果验证,形成了一个完整的技术流程,为后续的医疗大模型开发提供了宝贵的经验。

标签: none

添加新评论