全流程实战:云端微调 Qwen2.5 到 Mac(M4) 本地量化部署保姆级教程
2026-01-16 22:00:00 # AI实战 # 模型部署

前言

在探索 AI 数字人项目的过程中,我们经常面临一个尴尬的场景:云端算力平台(如 AutoDL 等)虽然显卡强大适合训练,但磁盘空间通常非常紧张,无法容纳微调后的合并操作(往往需要 2-3 倍模型体积的空间)。而本地设备(如 Mac M4)拥有极强的推理性能和大容量硬盘,却不适合长时间的训练任务。

本文将手把手教你如何打通这两端:在云端只做训练,只下载几百 MB 的补丁(Adapter),然后在 Mac 本地完成高配置要求的模型合并与量化,最后实现 4-bit 高速推理。


第一阶段:云端微调与导出 (Linux)

场景:你已经在云端使用 LLaMA-Factory 完成了模型训练,输出路径为 ./model_output
痛点:尝试在服务器合并模型时提示磁盘空间不足 (No space left on device)。

1.1 放弃云端合并,只打包 Adapter

我们不需要在服务器上合并,只把微调生成的权重文件(Adapter)打包下载。

在服务器终端执行:

# 进入你的项目目录
cd /root/weclone/WeClone

# 压缩微调输出文件夹 (假设输出路径为 ./model_output)
tar -czvf adapter_output.tar.gz ./model_output

1.2 下载到本地

使用 WinSCP 或其他工具,将这个几百 MB 的 adapter_output.tar.gz 下载到你的 Mac 本地并解压。

  • 假设解压路径/Users/hao/Downloads/model_output

第二阶段:本地环境配置 (Mac M4)

回到你的 Mac,打开终端(Terminal),配置本地流水线。

2.1 安装基础 Python 库

Mac 自带 Python 3.9,直接安装所需的 AI 基础库:

pip3 install torch transformers peft accelerate protobuf sentencepiece gguf numpy

2.2 准备原始模型

既然服务器下载太慢,我们直接在 Mac 上下载原始模型 Qwen2.5-7B-Instruct。推荐使用 HuggingFace 或 ModelScope 下载。

  • 假设模型存放路径/Users/hao/Downloads/Qwen2.5-7B-Instruct

第三阶段:模型合并 (解决 16G 内存溢出)

核心问题:Mac M4 16GB 内存加载完整的 7B FP16 模型(约 15GB)非常吃力,普通的合并脚本会报 UserWarning: copying from a non-meta parameter... 甚至直接崩溃。我们需要利用 MacOS 的 Swap(虚拟内存)机制。

3.1 编写“强制 CPU”合并脚本

在下载目录新建文件 merge_model.py,写入以下代码:

import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel
import os
import gc

# =======================================================
# ⚠️ 请修改以下路径为你的真实路径
# =======================================================
base_model_path = "/Users/hao/Downloads/Qwen2.5-7B-Instruct"
adapter_path = "/Users/hao/Downloads/model_output"
output_path = "/Users/hao/Downloads/Qwen2.5_Merged_Final"
# =======================================================

print(f"🚀 开始加载原始模型: {base_model_path}")
print("⚠️ 注意:这一步会占满内存并使用硬盘交换(Swap),电脑可能会变卡,请耐心等待...")

try:
    tokenizer = AutoTokenizer.from_pretrained(base_model_path, trust_remote_code=True)
    
    # 关键修改:强制使用 CPU,避免 meta device 映射错误
    # device_map={"": "cpu"} 是解决 16G 内存报错的关键
    base_model = AutoModelForCausalLM.from_pretrained(
        base_model_path,
        torch_dtype=torch.float16,
        device_map={"": "cpu"}, 
        trust_remote_code=True
    )
    
    print("🧩 正在加载微调补丁 (Adapter)...")
    # Adapter 也强制加载到 CPU
    model_to_merge = PeftModel.from_pretrained(base_model, adapter_path, device_map={"": "cpu"})

    print("🔄 正在执行合并操作 (Merge and Unload)...")
    merged_model = model_to_merge.merge_and_unload()

    print(f"💾 正在保存完整模型到: {output_path}")
    merged_model.save_pretrained(output_path, safe_serialization=True)
    tokenizer.save_pretrained(output_path)
    print("🎉 合并成功!")

except Exception as e:
    print(f"❌ 发生错误: {e}")

3.2 运行合并脚本

python3 merge_model.py
  • 注意:运行期间内存压力会变大,等待几分钟即可生成约 15GB 的 Qwen2.5_Merged_Final 文件夹。

第四阶段:GGUF 量化与压缩

为了让模型在 LM Studio 里跑得飞快,我们需要将其转换为 GGUF 格式并压缩为 4-bit。

4.1 编译 llama.cpp 工具

llama.cpp 是进行 GGUF 转换的核心工具。

  1. 下载源码
    cd /Users/hao/Downloads
    git clone [https://github.com/ggerganov/llama.cpp](https://github.com/ggerganov/llama.cpp)
    cd llama.cpp
    
  1. 解决 CMake 问题
    如果运行 make 提示被弃用,或者 cmake 找不到,请执行:
    # 安装 cmake
    pip3 install cmake
    # 将 python bin 目录加入环境变量 (临时,防止找不到命令)
    export PATH="/Users/hao/Library/Python/3.9/bin:$PATH"
    
  1. **开始编译 (适配 Apple Silicon)**:
    cmake -B build
    cmake --build build --config Release -j 8
    

4.2 格式转换 (HF -> GGUF FP16)

先转为单文件 GGUF。
避坑指南:不要安装 requirements.txt 里的所有库(特别是 matplotlib 会版本冲突),只装核心库即可。

# 1. 安装转换脚本依赖
pip3 install gguf protobuf numpy

# 2. 执行转换 (生成临时的大文件,约 15GB)
python3 convert_hf_to_gguf.py \
  /Users/hao/Downloads/Qwen2.5_Merged_Final \
  --outfile /Users/hao/Downloads/temp_f16.gguf \
  --outtype f16

4.3 执行量化 (FP16 -> Q4_K_M)

使用编译好的 C++ 工具进行极致压缩。Q4_K_M 是目前 M 芯片上速度与精度平衡最好的选择。

./build/bin/llama-quantize \
  /Users/hao/Downloads/temp_f16.gguf \
  /Users/hao/Downloads/Qwen2.5-7B-Final-Q4_K_M.gguf \
  Q4_K_M
  • 成果:你将得到一个约 4.7GB.gguf 文件。

第五阶段:LM Studio 部署与 API 服务

5.1 解决“无法识别模型”的目录结构坑

很多新手直接把 .gguf 拖进文件夹,结果 LM Studio 扫描不到。
LM Studio 强制要求目录结构为: 发布者名/模型名/模型文件

请按以下结构整理你的文件:

/Users/hao/Documents/lmstudio
└── MyLocal                 <-- 一级目录:厂商名 (随便起)
    └── Qwen2.5-Final       <-- 二级目录:模型名
        └── Qwen2.5-7B-Final-Q4_K_M.gguf  <-- 你的模型文件

5.2 加载模型

  1. 打开 LM Studio,点击左侧文件夹图标 (My Models)。
  2. 设置路径为 /Users/hao/Documents/lmstudio
  3. 点击 Rescan Directory,加载并选择模型。

5.3 开启局域网访问 (API 服务)

  1. 点击左侧双向箭头图标 (Local Server)。
  2. 点击顶部 Start Server
  3. 关键设置:将右侧配置栏中的 Port -> Network InterfaceLocalhost 改为 **Local Network**。
  4. 现在,你可以通过 http://你的MacIP:1234/v1 在局域网内访问这个数字人服务了!

第六阶段:磁盘大扫除 (回血)

保留好最终的 4.7GB 文件后,我们可以删除几十 GB 的中间文件来释放空间。

# 删除原始庞大的模型文件夹
rm -rf /Users/hao/Downloads/Qwen2.5-7B-Instruct
rm -rf /Users/hao/Downloads/Qwen2.5_Merged_Final
rm -f /Users/hao/Downloads/temp_f16.gguf

# 删除编译工具和源码
rm -rf /Users/hao/Downloads/llama.cpp
rm -rf /Users/hao/Downloads/Merge_Work
rm -rf /Users/hao/Downloads/model_output

# 清理隐藏的 Python 和 HuggingFace 缓存 (这部分占用巨大)
rm -rf ~/.cache/huggingface
rm -rf ~/.cache/pip

总结

通过这套流程,我们成功绕过了云端磁盘限制,利用 Mac M4 强大的单核性能和统一内存架构,完成了高质量的私有模型部署。最终获得的 4-bit 模型在 M4 上推理速度极快,完全满足实时数字人交互的需求。