Qwen2.5-0.5B 模型微调与部署完整教程

Qwen2.5-0.5B 模型微调与部署完整教程

一、教程简介

本教程将带你完成 Qwen2.5-0.5B 模型的微调、转换和部署全流程。你将学习如何在 CPU 环境下微调模型,将其转换为 GGUF 格式,并部署到 Ollama 中使用。

目标读者

  • 想要学习大模型微调的初学者
  • 没有高端 GPU 但想尝试微调模型的开发者
  • 希望将微调模型部署到本地的用户

技术栈

  • Python 3.10
  • PyTorch 2.9.1
  • Transformers 4.57.6
  • PEFT (LoRA 技术)
  • Ollama
  • llama.cpp

二、环境搭建

1. 创建虚拟环境

使用 conda 创建一个独立的虚拟环境,避免依赖冲突:

bash 复制代码
# 创建虚拟环境
conda create -n qwen_finetune python=3.10 -y

# 激活环境
conda activate qwen_finetune

2. 安装依赖包

安装微调所需的所有依赖:

bash 复制代码
# 创建 requirements.txt 文件
touch requirements.txt

将以下内容复制到 requirements.txt 中:

txt 复制代码
transformers>=4.37.0
datasets
accelerate
peft
torch
trl
scipy
scikit-learn
numpy
tensorboard
modelscope

然后安装依赖:

bash 复制代码
pip install -r requirements.txt

三、数据准备

1. 准备训练数据

创建 train_data.json 文件,包含你的训练数据。数据格式为 messages 格式,这是 Qwen2.5 模型推荐的格式:

json 复制代码
[
  {
    "messages": [
      {
        "role": "user",
        "content": "《中华人民共和国科学技术普及法》的立法目的是什么?"
      },
      {
        "role": "assistant",
        "content": "根据《中华人民共和国科学技术普及法》第一条,立法目的是:为了实施科教兴国战略、人才强国战略和创新驱动发展战略,全面促进科学技术普及,加强国家科学技术普及能力建设,提高公民的科学文化素质,推进实现高水平科技自立自强,推动经济发展和社会进步,根据宪法,制定本法。"
      }
    ]
  },
  {
    "messages": [
      {
        "role": "user",
        "content": "《中华人民共和国科学技术普及法》适用于哪些活动?"
      },
      {
        "role": "assistant",
        "content": "根据第二条,本法适用于国家和社会普及科学技术知识、倡导科学方法、传播科学思想、弘扬科学精神的活动。开展科普应当采取公众易于接触、理解、接受、参与的方式。"
      }
    ]
  },
    // 更多训练数据...
]

2. 数据要求

  • 建议包含 100-1000 条训练数据
  • 每条数据包含 messages 数组,其中包含 userassistant 角色
  • 确保数据质量,避免错误信息
  • 可以包含不同领域的知识,如法律、科普、常识等

3. 自动生成训练数据(可选)

如果你有特定的文档需要生成训练数据,可以使用提供的 extract_data.py 脚本自动生成问答对。例如,从法律文本中提取条款问答:

bash 复制代码
python extract_data.py

该脚本会从 中华人民共和国科学技术普及法.docx 中提取法律条款,并生成问答对添加到 train_data.json 文件中。

四、模型微调

1. 编写训练脚本

创建 train.py 文件,包含以下代码:

python 复制代码
# train.py - Qwen2.5-0.5B LoRA 微调脚本 (CPU优化版)
import os
import torch
from transformers import (
    AutoModelForCausalLM,
    AutoTokenizer,
    TrainingArguments,
    Trainer,
    DataCollatorForSeq2Seq,
)
from peft import LoraConfig, get_peft_model, TaskType, prepare_model_for_kbit_training
from datasets import load_dataset
from transformers import EvalPrediction
import numpy as np

# ================== 配置区域 ==================
# 使用modelscope镜像源的模型路径
MODEL_NAME = "qwen/Qwen2.5-0.5B-Instruct"    # modelscope模型名称
DATA_PATH = "train_data.json"                # 数据文件
OUTPUT_DIR = "./output"                     # 输出目录
MAX_LENGTH = 64                             # 减小最大长度,降低内存使用
MODEL_CACHE_DIR = "./model_cache"           # 模型缓存目录
USE_MODELSCOPE = True                        # 是否使用modelscope下载模型

# 检查是否使用modelscope
if USE_MODELSCOPE:
    from modelscope import snapshot_download
    print("已启用modelscope下载模式")

# ================== 检查环境 ==================
print("=" * 50)
print("环境检查")
print("=" * 50)
print(f"PyTorch版本: {torch.__version__}")
print(f"CUDA可用: {torch.cuda.is_available()}")
print(f"使用设备: {'CPU' if not torch.cuda.is_available() else 'GPU'}")

# ================== 加载数据集 ==================
print("\n" + "=" * 50)
print("加载数据集")
print("=" * 50)
dataset = load_dataset("json", data_files=DATA_PATH)
print(f"数据集大小: {len(dataset['train'])}")

# 分割数据集为训练集和验证集 (8:2比例)
dataset = dataset["train"].train_test_split(test_size=0.2, seed=42)
print(f"训练集大小: {len(dataset['train'])}")
print(f"验证集大小: {len(dataset['test'])}")

# ================== 加载模型和分词器 ==================
print("\n" + "=" * 50)
print("加载模型和分词器")
print("=" * 50)

# 模型路径处理
model_path = MODEL_NAME

# 如果使用modelscope,先下载模型到本地
if USE_MODELSCOPE:
    print(f"从modelscope下载模型: {MODEL_NAME}")
    model_path = snapshot_download(
        MODEL_NAME,
        cache_dir=MODEL_CACHE_DIR,
        revision="master"
    )
    print(f"模型下载完成,保存到: {model_path}")

# 加载分词器
tokenizer = AutoTokenizer.from_pretrained(
    model_path, 
    use_fast=False,
    cache_dir=MODEL_CACHE_DIR,
    trust_remote_code=True,
)
tokenizer.pad_token = tokenizer.eos_token

# 加载模型(使用CPU)
model = AutoModelForCausalLM.from_pretrained(
    model_path,
    dtype=torch.float32,                # 使用float32减少内存使用
    device_map="cpu",                   # 强制使用CPU
    cache_dir=MODEL_CACHE_DIR,          # 模型缓存目录
    trust_remote_code=True,
    low_cpu_mem_usage=True,             # 启用低CPU内存使用模式
)

# 准备模型用于训练
model = prepare_model_for_kbit_training(model)

# ================== 配置LoRA ==================
print("\n" + "=" * 50)
print("配置LoRA")
print("=" * 50)
lora_config = LoraConfig(
    task_type=TaskType.CAUSAL_LM,
    target_modules=["q_proj", "k_proj"],  # 只训练部分模块,减少内存使用
    inference_mode=False,
    r=16,                                 # 降低LoRA秩,减少内存使用
    lora_alpha=64,                         # 降低alpha值
    lora_dropout=0.1,                      # 增加dropout,减少过拟合
)

# 应用LoRA
model = get_peft_model(model, lora_config)
model.print_trainable_parameters()

# ================== 数据预处理 ==================
print("\n" + "=" * 50)
print("数据预处理")
print("=" * 50)

def process_func(example):
    # 直接使用数据中的messages格式
    messages = example['messages']
    
    # 使用模型自带的tokenizer.apply_chat_template处理
    text = tokenizer.apply_chat_template(
        messages,
        tokenize=False,
        add_generation_prompt=False
    )
    
    # 分词
    tokenized = tokenizer(
        text,
        max_length=MAX_LENGTH,
        truncation=True,
        padding="max_length",
    )
    
    # 设置标签
    tokenized["labels"] = tokenized["input_ids"].copy()
    return tokenized

# 处理数据集
tokenized_dataset = dataset.map(process_func, remove_columns=dataset["train"].column_names)

# ================== 配置训练参数 ==================
print("\n" + "=" * 50)
print("配置训练参数")
print("=" * 50)
training_args = TrainingArguments(
    output_dir=OUTPUT_DIR,
    per_device_train_batch_size=1,  # 保持小批量
    gradient_accumulation_steps=16,  # 增加梯度累积,进一步减少内存使用
    learning_rate=2e-4,  # 学习率
    num_train_epochs=2,   # 减少训练轮数,降低内存占用
    logging_steps=20,  # 减少日志频率
    save_steps=100,  # 减少保存频率
    save_total_limit=1,  # 只保存一个检查点
    lr_scheduler_type="cosine",
    warmup_ratio=0.05,  # 减少预热比例
    fp16=False,  # CPU不支持fp16
    bf16=False,  # CPU不支持bf16
    optim="adamw_torch",
    report_to=[],  # 禁用报告,减少内存使用
    seed=42,
    remove_unused_columns=True,  # 移除未使用的列,减少内存
    dataloader_num_workers=0,  # 禁用多进程数据加载
)

# ================== 配置评估 ==================
print("\n" + "=" * 50)
print("配置评估")
print("=" * 50)

# 处理验证集
tokenized_val_dataset = dataset["test"].map(process_func, remove_columns=dataset["test"].column_names)

# ================== 开始训练 ==================
print("\n" + "=" * 50)
print("开始训练")
print("=" * 50)

trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=tokenized_dataset["train"],
    eval_dataset=tokenized_val_dataset,
    data_collator=DataCollatorForSeq2Seq(tokenizer=tokenizer, padding=True),
    # 暂时不使用复杂的评估函数,避免内存问题
    compute_metrics=None,
)

# 开始训练
trainer.train()

# 评估模型在验证集上的表现
print("\n" + "=" * 50)
print("评估模型")
print("=" * 50)
eval_results = trainer.evaluate()
print(f"\n评估结果: {eval_results}")

# ================== 保存模型 ==================
print("\n" + "=" * 50)
print("保存模型")
print("=" * 50)

# 保存LoRA权重
model.save_pretrained(os.path.join(OUTPUT_DIR, "lora_weights"))
tokenizer.save_pretrained(os.path.join(OUTPUT_DIR, "lora_weights"))

print(f"\n训练完成!模型保存到: {OUTPUT_DIR}")
print("\n下一步:将LoRA权重合并到基础模型并转换为ollama格式")

2. 开始微调

运行训练脚本开始微调:

bash 复制代码
python train.py

3. 训练过程说明

  • 训练脚本会自动从 modelscope 下载模型
  • 训练过程会显示环境信息、数据集大小、模型配置等
  • 训练完成后,LoRA 权重会保存到 ./output/lora_weights 目录
  • 训练时间取决于你的 CPU 性能

五、合并模型权重

训练完成后,需要将 LoRA 权重合并到基础模型中。我们使用专门的 merge_model.py 脚本来完成这个过程:

1. 创建合并脚本

创建 merge_model.py 文件,包含以下代码:

python 复制代码
# 合并LoRA权重到基础模型
import os
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel

# ================== 配置区域 ==================
BASE_MODEL_PATH = "./model_cache/qwen/Qwen2___5-0___5B-Instruct"
LORA_PATH = "./output/lora_weights"
OUTPUT_DIR = "./merged_model"

# ================== 合并模型 ==================
print("开始合并模型...")

# 加载基础模型
base_model = AutoModelForCausalLM.from_pretrained(
    BASE_MODEL_PATH,
    torch_dtype=torch.float32,
    device_map="cpu",
    trust_remote_code=True,
)

# 加载分词器
tokenizer = AutoTokenizer.from_pretrained(
    BASE_MODEL_PATH,
    trust_remote_code=True,
)

# 加载LoRA模型
model = PeftModel.from_pretrained(base_model, LORA_PATH, device_map="cpu")

# 合并权重
print("合并权重中...")
model = model.merge_and_unload()

# 保存合并后的模型
os.makedirs(OUTPUT_DIR, exist_ok=True)
print(f"保存模型到 {OUTPUT_DIR}...")
model.save_pretrained(OUTPUT_DIR, safe_serialization=True)
tokenizer.save_pretrained(OUTPUT_DIR)

print("模型合并完成!")

2. 运行合并脚本

bash 复制代码
python merge_model.py

注意事项

  • 确保模型路径正确,根据实际下载的模型目录调整路径
  • 合并过程可能需要几分钟时间
  • 合并后的模型会保存到 ./merged_model 目录
  • 合并后的模型文件大小约为 1GB

六、模型转换(GGUF格式)

1. 克隆 llama.cpp 仓库

llama.cpp 是一个高效的大模型推理库,我们需要使用它来将合并后的模型转换为 GGUF 格式。

1.1 检查 Git 是否安装

首先,确保你的系统已经安装了 Git:

bash 复制代码
# 检查 Git 版本
git --version

如果没有安装 Git,你需要先安装它。在 Windows 上,你可以从 Git 官网 下载并安装。

1.2 克隆仓库

使用国内镜像源克隆 llama.cpp 仓库,确保克隆完整:

bash 复制代码
# 使用 gitee 镜像克隆(推荐,国内访问速度快)
git clone https://gitee.com/mirrors/llama-cpp.git

# 或者使用 github 原仓库
git clone https://github.com/ggerganov/llama.cpp.git

# 如果需要指定克隆目录名称,可以使用以下格式
git clone https://gitee.com/mirrors/llama-cpp.git my-llama-cpp
1.3 处理克隆失败

如果克隆失败,可能是网络问题或权限问题。你可以尝试以下解决方案:

bash 复制代码
# 1. 检查网络连接
ping gitee.com

# 2. 增加超时时间
git clone --timeout=120 https://gitee.com/mirrors/llama-cpp.git

# 3. 启用浅层克隆(只克隆最近的提交,减少网络传输)
git clone --depth=1 https://gitee.com/mirrors/llama-cpp.git

# 4. 检查代理设置
# 如果你使用代理,可以设置 Git 代理
git config --global http.proxy http://proxy.example.com:8080
git config --global https.proxy https://proxy.example.com:8080

# 5. 如果不需要 Git 历史,可以直接下载 ZIP 压缩包
# 使用浏览器访问:https://gitee.com/mirrors/llama-cpp/archive/master.zip
1.4 检查克隆结果

克隆完成后,检查目录结构是否完整:

bash 复制代码
# 查看 llama-cpp 目录内容
dir llama-cpp

# 或者使用更详细的列表
dir /s llama-cpp

你应该能看到以下关键文件和目录:

  • convert_hf_to_gguf.py - Hugging Face 模型转 GGUF 格式的脚本
  • convert_llama_ggml_to_gguf.py - GGML 模型转 GGUF 格式的脚本
  • src/ - 源代码目录
  • gguf-py/ - GGUF Python 库
  • CMakeLists.txt - CMake 构建配置文件
  • README.md - 项目说明文档
1.5 查看克隆版本信息

查看当前克隆的版本和提交信息:

bash 复制代码
cd llama-cpp
# 查看当前分支和最新提交
git status
git log -1
cd ..
1.6 更新到最新版本(可选)

如果需要使用最新功能,可以更新到最新版本:

bash 复制代码
cd llama-cpp
git pull origin master
cd ..

# 如果要切换到特定分支
git checkout dev

# 如果要切换到特定标签(版本)
git checkout v0.2.78
1.7 验证仓库完整性

确保仓库中的关键脚本存在且可访问:

bash 复制代码
# 检查转换脚本是否存在
if exist "llama-cpp\convert_hf_to_gguf.py" (
    echo "转换脚本存在"
) else (
    echo "转换脚本不存在,请重新克隆仓库"
)

2. 准备 llama.cpp 环境

在使用 llama.cpp 进行模型转换前,需要安装相关依赖:

2.1 安装 Python 依赖

转换脚本需要一些 Python 依赖,确保安装它们:

bash 复制代码
# 进入 llama.cpp 目录
cd llama-cpp

# 安装 gguf-py 依赖(使用 pyproject.toml)
pip install -e ./gguf-py

# 安装转换脚本所需的其他依赖
pip install -r requirements.txt

cd ..
2.2 编译 llama.cpp(可选,推荐)

虽然 Python 转换脚本可以直接使用,但编译 llama.cpp 可以获得更好的性能,特别是用于后续的模型推理:

Windows 系统编译步骤:

bash 复制代码
# 进入 llama.cpp 目录
cd llama-cpp

# 使用 CMake 生成构建文件
mkdir -p build
cd build
cmake .. -G "MinGW Makefiles"

# 编译
mingw32-make -j4

# 检查编译结果
if exist "main.exe" (
    echo "编译成功!生成了 main.exe 可执行文件"
) else (
    echo "编译失败,请检查错误信息"
)

cd ../..

注意: 编译需要安装 MinGW-w64 或 Visual Studio。如果遇到编译问题,可以跳过此步骤,直接使用 Python 转换脚本。

3. 转换模型格式

使用 llama.cpp 提供的 convert_hf_to_gguf.py 脚本将合并后的模型转换为 GGUF 格式:

bash 复制代码
# 确保在项目根目录下执行
python llama-cpp\convert_hf_to_gguf.py merged_model --outfile qwen2.5-0.5b-finetuned.gguf
3.1 转换参数说明

你可以根据需要调整转换参数:

bash 复制代码
# 添加 --outtype 参数指定输出类型(默认是 float16)
python llama-cpp\convert_hf_to_gguf.py merged_model --outfile qwen2.5-0.5b-finetuned.gguf --outtype f16

# 或者使用量化输出类型(如 q4_0,会自动执行量化)
python llama-cpp\convert_hf_to_gguf.py merged_model --outfile qwen2.5-0.5b-finetuned-q4_0.gguf --outtype q4_0

# 指定转换时使用的线程数
python llama-cpp\convert_hf_to_gguf.py merged_model --outfile qwen2.5-0.5b-finetuned.gguf --threads 4

# 查看所有可用参数
python llama-cpp\convert_hf_to_gguf.py --help
3.2 支持的输出类型

llama.cpp 支持多种 GGUF 输出类型,常见的有:

类型 描述 模型大小 推荐场景
f32 32位浮点 约4GB 最高精度要求
f16 16位浮点 约2GB 平衡精度和大小
q8_0 8位量化 约1GB 基本量化,保留较好精度
q4_0 4位量化 约500MB 推荐,平衡性能和质量
q4_1 4位量化(增强) 约550MB 比q4_0精度更高
q5_0 5位量化 约625MB 精度更高,适合对质量要求高的场景
q5_1 5位量化(增强) 约675MB 最高质量的4-5位量化
q2_k 2位量化 约250MB 极致压缩,适合资源受限设备

4. 转换过程说明

  • 转换脚本会读取 merged_model 目录下的模型文件
  • 将 PyTorch 模型权重转换为 GGUF 格式
  • 转换过程会显示详细的转换日志,包括每层的转换情况
  • 转换后的模型文件大小约为(针对 Qwen2.5-0.5B):
    • float16 格式:约 988MB
    • q4_0 量化格式:约 250MB
    • q4_1 量化格式:约 290MB
  • 转换过程可能需要 1-5 分钟时间,取决于你的 CPU 性能

5. 验证转换结果

转换完成后,检查生成的 GGUF 文件:

bash 复制代码
# 查看生成的 GGUF 文件
dir qwen2.5-0.5b-finetuned*.gguf

你应该能看到生成的 GGUF 文件,接下来我们将使用它来部署到 Ollama。

6. 使用编译后的 llama.cpp 验证模型(可选)

如果成功编译了 llama.cpp,可以使用编译后的程序验证转换后的模型:

bash 复制代码
# 使用编译后的 main.exe 验证模型
llama-cpp\build\main.exe -m qwen2.5-0.5b-finetuned.gguf -p "你好,我是" -n 10 --color

这将使用转换后的模型生成一段文本,验证模型是否能正常工作。

七、部署到 Ollama

1. 创建 modelfile.txt

创建 modelfile.txt 文件,包含模型配置:

bash 复制代码
type nul > modelfile.txt

将以下内容复制到文件中:

复制代码
FROM qwen2.5-0.5b-finetuned.gguf

TEMPLATE """{{- if .Messages }}
{{- if or .System .Tools }}<|im_start|>system
{{- if .System }}
{{ .System }}
{{- end }}
{{- if .Tools }}

# Tools

You may call one or more functions to assist with the user query.

You are provided with function signatures within <tools></tools> XML tags:
<tools>
{{- range .Tools }}
{"type": "function", "function": {{ .Function }}}
{{- end }}
</tools>

For each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:
<tool_call>
{"name": <function-name>, "arguments": <args-json-object>}
</tool_call>
{{- end }}<|im_end|>
{{ end }}
{{- range $i, $_ := .Messages }}
{{- $last := eq (len (slice $.Messages $i)) 1 -}}
{{- if eq .Role "user" }}<|im_start|>user
{{ .Content }}<|im_end|>
{{ else if eq .Role "assistant" }}<|im_start|>assistant
{{ if .Content }}{{ .Content }}
{{- else if .ToolCalls }}<tool_call>
{{ range .ToolCalls }}{"name": "{{ .Function.Name }}", "arguments": {{ .Function.Arguments }}}
{{ end }}</tool_call>
{{- end }}{{ if not $last }}<|im_end|>
{{ end }}
{{- else if eq .Role "tool" }}<|im_start|>user
<tool_response>
{{ .Content }}
</tool_response><|im_end|>
{{ end }}
{{- if and (ne .Role "assistant") $last }}<|im_start|>assistant
{{ end }}
{{- end }}
{{- else }}
{{- if .System }}<|im_start|>system
{{ .System }}<|im_end|>
{{ end }}{{ if .Prompt }}<|im_start|>user
{{ .Prompt }}<|im_end|>
{{ end }}<|im_start|>assistant
{{ end }}{{ .Response }}{{ if .Response }}<|im_end|>{{ end }}"""
SYSTEM "你是一个经过微调的AI助手,很高兴为您服务!"
PARAMETER temperature 0.7
PARAMETER top_p 0.95

2. 删除现有模型(如果存在)

如果之前已经创建过同名模型,需要先删除:

bash 复制代码
ollama rm qwen2.5-0.5b-finetuned

3. 创建 Ollama 模型

使用 ollama create 命令创建模型:

bash 复制代码
ollama create qwen2.5-0.5b-finetuned -f modelfile.txt

4. 验证模型

使用 ollama list 命令查看创建的模型:

bash 复制代码
ollama list

你应该能看到 qwen2.5-0.5b-finetuned 模型。

八、使用微调模型

1. 命令行使用

使用 ollama run 命令运行模型:

bash 复制代码
ollama run qwen2.5-0.5b-finetuned "你是谁?"

2. API 使用

Ollama 默认在后台运行服务,你可以直接使用 API 调用模型:

bash 复制代码
curl http://localhost:11434/api/generate -d '{"model": "qwen2.5-0.5b-finetuned", "prompt": "你是谁?"}'

3. 测试示例

测试模型是否能够回答你的训练数据中的问题:

bash 复制代码
# 测试法律条款问题
ollama run qwen2.5-0.5b-finetuned "《中华人民共和国科学技术普及法》第5条的内容是什么?"

# 测试常识问题
ollama run qwen2.5-0.5b-finetuned "水的化学式是什么?"

九、常见问题与解决方案

1. 网络问题无法下载模型

解决方案

  • 使用国内镜像源(modelscope、gitee)
  • 手动下载模型并指定本地路径
  • 检查网络连接和代理设置
  • 确保 model_cache 目录有写入权限

2. 内存不足(页面文件太小)

解决方案

  • 减少 MAX_LENGTH 参数值(建议设置为 64-128)
  • 降低 per_device_train_batch_size
  • 增加 gradient_accumulation_steps 到 16 或更高
  • 使用更小的 LoRA 秩(r 值设为 8 或 16)
  • 减少 LoRA 训练的目标模块(只训练 q_proj 和 k_proj)
  • 关闭不必要的后台程序
  • 增加系统虚拟内存(页面文件大小)

3. 模型转换失败

解决方案

  • 确保 llama.cpp 目录结构完整
  • 检查合并后的模型文件完整性(查看 merged_model 目录下的文件)
  • 确保 Python 版本兼容(建议使用 Python 3.10)
  • 尝试更新 llama.cpp 到最新版本

4. Ollama 模型创建失败

解决方案

  • 检查 modelfile.txt 格式是否正确
  • 确保 GGUF 文件路径正确(相对路径或绝对路径)
  • 先删除现有同名模型再重新创建
  • 查看 Ollama 日志获取详细错误信息
  • 确保 Ollama 版本兼容 GGUF 格式

5. 训练后模型回答不准确

解决方案

  • 增加训练数据量(建议至少 100 条)
  • 提高训练轮数(增加 num_train_epochs)
  • 调整学习率(尝试不同的 lr 值)
  • 检查训练数据质量和格式
  • 确保数据格式为正确的 messages 格式

十、优化建议

  1. 增加训练数据:使用更多高质量的训练数据(100-1000 条)
  2. 调整训练参数:尝试不同的学习率、批次大小等
  3. 使用量化技术:转换时使用不同的量化级别(q4_0、q4_1 等)
  4. 监控训练过程:使用 tensorboard 查看训练曲线
  5. 评估模型性能:使用测试集评估微调效果
  6. 数据增强:对训练数据进行多样化处理,提高模型泛化能力
  7. 使用多轮对话数据:如果任务需要,可以添加多轮对话训练数据
  8. 调整 LoRA 配置:尝试不同的 LoRA 秩和 alpha 值
  9. 使用早期停止:监控验证损失,避免过拟合
  10. 模型集成:尝试将多个微调模型的结果进行集成

十一、总结

通过本教程,你已经学会了:

  1. 搭建 Qwen2.5-0.5B 微调环境
  2. 准备 messages 格式的训练数据
  3. 使用 LoRA 技术在 CPU 上微调模型
  4. 合并模型权重
  5. 将模型转换为 GGUF 格式
  6. 部署模型到 Ollama 中使用
  7. 测试和评估微调模型

本教程提供了一个完整的 Qwen2.5-0.5B 模型微调流程,从数据准备到模型部署,适合没有高端 GPU 的开发者尝试。你可以根据自己的需求进一步优化模型,或者将其集成到你的应用中。

微调大模型是一个迭代过程,需要不断调整参数和数据,才能获得理想的效果。祝你在大模型微调的道路上越走越远!

十二、参考资源


测试环境:Windows 11, Python 3.10, CPU

本教程基于 Qwen2.5-0.5B 模型,在 Windows 11 系统下使用 CPU 环境测试通过。不同环境可能需要适当调整命令和配置。


温馨提示:大模型微调是一个迭代过程,建议根据实际情况调整参数和流程。如果遇到问题,可以参考常见问题部分,或者在相关社区寻求帮助。

相关推荐
core5121 天前
使用 `ms-swift` 微调 Qwen3-VL-2B 详细指南
lora·微调·swift·qwen·qwen3·vl
core5121 天前
Swift SFT Qwen-VL LoRA 微调指令详解
lora·微调·swift·qwen·vl
Mr.Ja1 天前
[特殊字符] 虚拟机部署 Redis 详细教程(从安装到安全验证全流程)
redis·部署·虚拟机·redis部署
Aspect of twilight2 天前
QwenVL 模型输入细节
人工智能·qwen
刘金宝_Arvin2 天前
【Data Agent】数据分析智能体 初体验,可用的Chat BI -- 本地部署使用全流程
qwen·ollama·data agent
高性能服务器4 天前
AGI-Next 闭门峰会深度纪要:中国AI的3小时深度思辨
agent·agi·qwen·智谱ai·agi-next闭门峰会·阿里千问·模型即产品
jjjddfvv5 天前
超级简单启动llamafactory!
windows·python·深度学习·神经网络·微调·audiolm·llamafactory
_小苔藓_5 天前
混合Token与LoRA结合Qwen3-VL高效微调(代码开源)
深度学习·开源·大模型·微调·多模态
田井中律.8 天前
七种大模型方法
微调