Qwen2.5-7B 微调与部署全流程 SOP


写在文前:没想到最后也屈服于 AI 了,在各种资料和 Gemini 的帮助下完成了一次微调和部署流程

项目目标:基于 Qwen2.5-7B-Instruct 模型,使用 PsyQA 数据集微调一个具备共情能力的心理咨询 AI,并量化部署到 Ollama。

硬件环境:NVIDIA 5090 32G + 100G 可用磁盘空间

基座模型Qwen/Qwen2.5-7B-Instruct

第一阶段:环境与数据准备

1. 环境搭建

推荐使用 Conda 创建独立环境,防止依赖冲突。

Bash

# 1. 创建并激活虚拟环境
conda create -n qwen_finetune python=3.10 -y
conda activate qwen_finetune

# 2. 克隆 LLaMA-Factory
git clone --depth 1 https://github.com/hiyouga/LLAMA-Factory.git
cd LLAMA-Factory

# 3. 安装核心依赖
pip install -e ".[torch,metrics]" -i https://pypi.tuna.tsinghua.edu.cn/simple

# 4. 安装加速库 (Flash Attention 2)
# 注意:这步极易报错,确保 CUDA 版本与 Torch 匹配
pip install flash-attn --no-build-isolation

2. 数据处理与清洗

将 HF 格式转换为 LLaMA-Factory 支持的 Alpaca/JSONL 格式。

脚本:preprocess_psyqa.py

Python

import json
from datasets import load_dataset

def format_psyqa(output_file):
    print("正在加载数据集 lsy641/PsyQA ...")
    try:
        # 建议先下载到本地 /root/autodl-tmp/data/ 避免网络中断
        dataset = load_dataset("lsy641/PsyQA", split="train") 
    except Exception as e:
        print(f"加载失败: {e}")
        return

    print(f"原始数据量: {len(dataset)}")
    formatted_data = []
    system_prompt = "你是一位共情能力强、专业的心理咨询师。请根据求助者的描述,给出温暖、建设性的建议。"

    for item in dataset:
        question = item.get('description', '') or item.get('question', '')
        answer = item.get('answer', '')

        # 简单清洗
        if len(question) < 10 or len(answer) < 10:
            continue

        formatted_data.append({
            "instruction": system_prompt,
            "input": question,
            "output": answer
        })

    with open(output_file, 'w', encoding='utf-8') as f:
        json.dump(formatted_data, f, ensure_ascii=False, indent=2)

    print(f"✅ 处理完成!有效数据: {len(formatted_data)} 条。保存至: {output_file}")

if __name__ == "__main__":
    # 确保 data 目录存在
    import os
    os.makedirs("data", exist_ok=True)
    format_psyqa("data/psyqa_formatted.json")

生成文本样例:

{
  "instruction": "你是一位共情能力强、专业的心理咨询师。请根据求助者的描述,给出温暖、建设性的建议。",
  "input": "我想实现自己的目标,但是心灵匮乏,没有能量,所以行动力很低心灵能量如何补?",
  "output": "楼主你好呀,给你温暖的抱抱~在你的问题描述中,你能够感知到自己是一个有目标的人,但是你却缺乏【能量】,这能量更学术一点的来说,就是动机。给我们做出行为反应的更多的就是我们的动机,当我们的动机越强烈越明确的时候,我们就能够越高效的、迅速的做出行为反应。或许你需要去寻找这个目标对你来说的意义,你为什么渴望有这样的一个目标?在这你还需要去完善你的行动,可能你有很强烈的需求去促进你的行为,但是可能在时间的安排上,你会耽误一些。可以试着给自己进行一个规划,通过一个大的目标来分解为小目标,进而制定一个适合自己的计划,通过细分能够更好地促进自己行为的发生。祝好~。"
}

3. 注册数据集

LLaMA-Factory 必须在 dataset_info.json 中注册数据才能识别。编辑 LLAMA-Factory/data/dataset_info.json,在文件末尾(大括号内)添加:

JSON

  "psyqa": {
    "file_name": "psyqa_formatted.json",
    "columns": {
      "prompt": "instruction",
      "query": "input",
      "response": "output"
    }
  }

第二阶段:LoRA 微调 (SFT)

1. 启动训练

建议保存为 run_train.sh 并运行。

  • ⚠️ 显存注意:如果你显存小于 24GB,请调低 per_device_train_batch_size 为 1,并调高 gradient_accumulation_steps
#!/bin/bash
CUDA_VISIBLE_DEVICES=0 llamafactory-cli train \
    --stage sft \
    --do_train \
    --model_name_or_path Qwen/Qwen2.5-7B-Instruct \
    --dataset psyqa \
    --dataset_dir ./data \
    --template qwen \
    --finetuning_type lora \
    --lora_target all \
    --output_dir saves/Qwen2.5-7B-PsyQA/lora/sft \
    --overwrite_output_dir \
    --per_device_train_batch_size 2 \
    --gradient_accumulation_steps 8 \
    --lr_scheduler_type cosine \
    --logging_steps 10 \
    --save_steps 500 \
    --learning_rate 1e-4 \
    --num_train_epochs 3.0 \
    --max_samples 10000 \
    --max_grad_norm 1.0 \
    --lora_rank 32 \
    --lora_alpha 64 \
    --lora_dropout 0.1 \
    --plot_loss \
    --bf16 \
    --gradient_checkpointing

第三阶段:验证与合并

1. 快速对话测试 (Check LoRA)

验证 Adapter 是否有效。

llamafactory-cli chat \
    --model_name_or_path Qwen/Qwen2.5-7B-Instruct \
    --adapter_name_or_path saves/Qwen2.5-7B-PsyQA/lora/sft \
    --template qwen \
    --finetuning_type lora

2. 模型合并 (Merge)

将 LoRA 权重合入基座,生成完整模型。 ⚠️ 路径注意:请根据实际下载位置调整 /root/autodl-tmp/...

# 确保在 LLAMA-Factory 目录下
llamafactory-cli export \
    --model_name_or_path Qwen/Qwen2.5-7B-Instruct \
    --adapter_name_or_path ./saves/Qwen2.5-7B-PsyQA/lora/sft \
    --template qwen \
    --finetuning_type lora \
    --export_dir /root/autodl-tmp/Qwen2.5-7B-PsyQA-Merged \
    --export_size 5 \
    --export_device cpu

第四阶段:GGUF 量化与部署 (AutoDL -> 本地)

1. 编译 llama.cpp

修复点:针对 AutoDL 环境,需安装 cmakelibcurl

cd /root/autodl-tmp
git clone --depth=1 https://github.com/ggerganov/llama.cpp.git
cd llama.cpp

# 安装依赖防止编译报错
apt-get update && apt-get install -y cmake libcurl4-openssl-dev

# 使用 CMake 编译 (生成工具在 build/bin 下)
mkdir build && cd build
cmake ..
cmake --build . --config Release -j $(nproc)

2. 格式转换 (HF -> GGUF FP16)

⚠️ 空间预警:此步需要约 35GB 空闲空间。

# 回到 llama.cpp 根目录
cd /root/autodl-tmp/llama.cpp

# 执行转换 (使用绝对路径)
python convert_hf_to_gguf.py /root/autodl-tmp/Qwen2.5-7B-PsyQA-Merged/ \
  --outfile Qwen2.5-7B-PsyQA-f16.gguf \
  --outtype f16

3. 模型量化 (FP16 -> Q4_K_M)

将 14GB 的模型压缩至 5GB,适合本地运行。

# 注意工具路径在 build/bin
./build/bin/llama-quantize Qwen2.5-7B-PsyQA-f16.gguf Qwen2.5-7B-PsyQA-q4_k_m.gguf Q4_K_M

4. 备份到 Hugging Face (推荐)

防止 AutoDL 数据丢失。需先在 HF 申请 Write 权限 Token。

pip install huggingface_hub
huggingface-cli login # 输入 Token

huggingface-cli upload 你的HF用户名/Qwen2.5-7B-PsyQA \
    /root/autodl-tmp/llama.cpp/Qwen2.5-7B-PsyQA-q4_k_m.gguf \
    Qwen2.5-7B-PsyQA-q4_k_m.gguf

第五阶段:本地 Ollama 运行

1. 编写 Modelfile

在本地电脑(存放 GGUF 的目录)新建文件 Modelfile

FROM ./Qwen2.5-7B-PsyQA-q4_k_m.gguf
TEMPLATE """{{ if .System }}<|im_start|>system
{{ .System }}<|im_end|>
{{ end }}{{ if .Prompt }}<|im_start|>user
{{ .Prompt }}<|im_end|>
{{ end }}<|im_start|>assistant
"""
SYSTEM "你是一位专业的心理咨询师,擅长共情、倾听。请先接纳用户情绪,再给出建议。"
PARAMETER temperature 0.7
PARAMETER num_ctx 4096

2. 导入与运行

# 导入
ollama create psyqa -f Modelfile

# 运行
ollama run psyqa

声明:AweiP Cache|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - Qwen2.5-7B 微调与部署全流程 SOP


且愿饮冰而热血不凉