Evaluation & Model Export After Fine-Tuning
[Translation Pending]\n\n# 第 11 期 | 微调效果评估与模型导出
🎯 学习目标
- 理解大语言模型微调后进行效果评估的重要性,并掌握常见评估指标。
- 熟练运用
lm-evaluation-harness框架,对微调后的 Google Gemma 模型进行基准测试。 - 学会解读 MMLU 和 HellaSwag 等通用基准测试结果,评估模型的泛化能力和专业知识水平。
- 掌握将微调后的 Gemma 模型导出为 GGUF 格式的流程,为 CPU 部署和边缘设备优化做准备。
- 了解模型卡 (Model Card) 的作用,以及如何在模型发布和版本管理中应用最佳实践。
📖 核心概念讲解
11.1 微调效果评估的必要性与常见指标
微调(Fine-tuning)是大语言模型(LLM)适应特定任务或数据集的关键步骤。然而,仅仅完成训练并不意味着成功。我们需要一套严谨的方法来量化模型改进的程度,识别潜在的问题(如过拟合),并确保模型在实际应用中表现良好。
评估的必要性:
- 量化改进: 客观衡量微调对模型性能带来的提升。
- 避免过拟合: 检查模型是否仅仅记住了训练数据,而在未见过的数据上表现不佳。
- 指导迭代: 评估结果为进一步的微调、数据增强或架构调整提供依据。
- 风险管理: 评估模型的鲁棒性、偏见和安全性,确保其符合伦理要求。
- 发布与对比: 提供标准化的性能数据,便于与其他模型进行比较,并向社区展示模型能力。
评估维度:
- 通用能力: 模型在广泛任务上的语言理解、推理和生成能力。
- 特定任务能力: 模型在微调目标任务上的精确度、召回率、F1 分数等。
- 鲁棒性: 模型对输入扰动(如拼写错误、同义词替换)的抵抗能力。
- 安全性与伦理: 模型是否产生有害、偏见或不当内容。
- 效率: 推理速度、内存占用等。
常见评估工具与指标:
lm-evaluation-harness: 一个广泛使用的 LLM 评估框架,支持多种模型和数百个基准数据集。- MMLU (Massive Multitask Language Understanding): 包含 57 个学科(如历史、法律、数学、医学等)的多项选择题,旨在衡量模型在广泛知识领域的理解和推理能力。分数范围 0-100%,越高越好。
- HellaSwag: 一个常识推理数据集,要求模型从多个看似合理的选项中选择最符合常识的句子。用于评估模型在日常情境中的推理能力。分数范围 0-100%,越高越好。
- ARC (AI2 Reasoning Challenge): 科学领域的多项选择题,分为挑战集和简单集,评估模型在科学推理方面的能力。
- TruthfulQA: 评估模型在面对易于产生错误答案的问题时,是否能给出真实、无误的回答,侧重于事实性和避免幻觉。
11.2 lm-evaluation-harness 简介与使用
lm-evaluation-harness 是一个由 EleutherAI 开发的强大工具,旨在标准化和简化大语言模型的评估过程。它提供了一个统一的接口,可以对各种模型(如 Hugging Face Transformers 模型、OpenAI API 模型等)在大量基准测试数据集上进行评估。
核心概念:
- Tasks (任务): 指的是具体的评估数据集和其对应的评估逻辑,例如
mmlu_stem、hellaswag等。 - Models (模型): 指的是待评估的语言模型,可以是本地加载的 Hugging Face 模型,也可以是远程 API。
- Datasets (数据集): 任务背后所依赖的原始数据。
安装:
pip install lm-evaluation-harness
# 如果需要评估Hugging Face模型,还需要安装transformers和pytorch
pip install transformers torch accelerate
基本用法:
通过 lm_eval 命令行工具,可以指定模型、任务以及其他参数来运行评估。
lm_eval --model hf \
--model_args pretrained=google/gemma-2b \
--tasks mmlu_stem,hellaswag \
--num_fewshot 0 \
--device cuda:0 \
--batch_size 4 \
--output_path ./eval_results/gemma_2b_base_eval.json
上述命令解释:
--model hf: 指定使用 Hugging Facetransformers库加载模型。--model_args pretrained=google/gemma-2b: 指定要评估的模型名称或本地路径。--tasks mmlu_stem,hellaswag: 指定要运行的评估任务列表,多个任务用逗号分隔。--num_fewshot 0: 指定是否使用 Few-shot 评估。0 表示 Zero-shot。--device cuda:0: 指定运行设备。--batch_size 4: 推理批处理大小。--output_path: 评估结果的保存路径。
11.3 MMLU 与 HellaSwag 分数解读
理解这些基准测试的含义和分数解读至关重要。
MMLU (Massive Multitask Language Understanding):
- 目的: 衡量模型在广泛的、多样化的知识领域中的理解、推理和泛化能力。
- 内容: 包含 57 个子任务,涵盖人文、社会科学、自然科学、工程等多个学科。每个子任务都是多项选择题。
- 分数解读: MMLU 报告的是所有子任务的平均准确率。
- 高分 (例如 70%+): 表明模型具有强大的通用知识和跨领域推理能力,在学术和专业领域表现出色。
- 中等分数 (例如 50-70%): 模型具备一定的知识储备,但在某些专业领域可能仍有不足。微调通常旨在提升特定领域的 MMLU 分数。
- 低分 (<50%): 模型在通用知识或理解方面存在显著缺陷。
- Few-shot / Zero-shot: MMLU 通常在 Few-shot (5-shot) 设置下评估,即在每个问题前提供几个示例,这更能反映模型在有上下文提示时的学习和推理能力。
HellaSwag:
- 目的: 评估模型在日常情境中的常识推理能力,即从多个看似合理的选项中选择最符合逻辑和常识的延续。
- 内容: 给出一段上下文,然后是四个可能的后续句子,模型需要选择最自然、最符合常识的一个。
- 分数解读: HellaSwag 报告的是选择正确选项的准确率。
- 高分 (例如 80%+): 表明模型具有出色的常识理解和推理能力,能够理解日常对话和情境的隐含意义。
- 中等分数 (例如 60-80%): 模型在多数常识情境中表现良好,但在一些微妙或复杂的情况下可能出错。
- 低分 (<60%): 模型在常识推理方面存在明显不足,可能产生不合逻辑的回答。
如何看待分数:
- 绝对值: 直接反映模型在该基准上的性能。
- 相对值: 将微调后的模型分数与基座模型(如原始 Gemma 2B/7B)、同等规模的其他开源模型,甚至 SOTA (State-of-the-Art) 模型进行比较。这能更清晰地看出微调带来的提升和模型所处的水平。
- 任务相关性: 对于特定应用场景,应优先关注与该任务最相关的评估指标。例如,如果模型用于法律咨询,那么法律相关的 MMLU 子任务分数会更重要。
11.4 模型导出:GGUF 格式详解
在微调完成后,模型通常以 Hugging Face transformers 格式(PyTorch .bin 或 TensorFlow .h5 文件和配置文件)存储。然而,这种格式在 CPU 上进行推理时效率不高,尤其是在资源受限的设备上。GGUF (Gemma GGML Unified Format) 是一种专门为 CPU 和边缘设备优化的大语言模型文件格式,它由 llama.cpp 项目引入,并迅速成为 CPU 推理的事实标准。
为什么选择 GGUF?
- CPU 友好: GGUF 格式设计时考虑了 CPU 的内存访问模式,能够更高效地利用 CPU 资源进行推理。
- 量化支持: GGUF 原生支持多种量化方案(如 Q4_K_M, Q5_K_M, Q8_0 等),可以将模型权重从 16 位浮点数(FP16)或 32 位浮点数(FP32)压缩到 8 位、5 位甚至 4 位整数,大幅减少模型文件大小和内存占用,同时保持可接受的性能损失。
- 跨平台: GGUF 文件可以在支持
llama.cpp的各种操作系统和硬件上运行,包括 Linux、macOS、Windows,甚至树莓派等嵌入式设备。 - 元数据: GGUF 文件可以包含丰富的元数据,如模型名称、作者、量化类型、上下文窗口大小等,便于管理和识别。
- 生态系统: 得到了 Ollama 等轻量级 LLM 运行时的广泛支持,部署极为便捷。
Gemma 到 GGUF 的转换流程:
由于 Gemma 模型是基于 transformers 库发布的,我们可以利用 llama.cpp 项目提供的转换脚本将其转换为 GGUF 格式。这个过程通常包括以下步骤:
- 加载模型: 使用 Hugging Face
transformers库加载微调后的 Gemma 模型。 - 转换权重: 使用
llama.cpp仓库中的convert.py脚本,将 PyTorch 格式的权重转换为 GGUF 格式。这个脚本会处理模型的架构、分词器和权重,并应用指定的量化。
GGUF 转换工具链:
llama.cpp 仓库是 GGUF 格式的核心。它提供了一个 Python 脚本 convert.py,用于将 Hugging Face transformers 模型转换为 GGUF。
# 首先克隆 llama.cpp 仓库
git clone https://github.com/ggerganov/llama.cpp.git
cd llama.cpp
# 安装必要的 Python 依赖
pip install -r requirements.txt
# 假设你的微调模型保存在 `./my_gemma_finetune` 目录下
# 运行转换脚本
# --outfile 指定输出的 GGUF 文件名
# --model_id 指定 Hugging Face 模型ID 或本地模型路径
# --quantization_type 指定量化类型 (可选,默认为 FP16)
# 例如,转换为 Q4_K_M 量化
python convert.py --outfile ../my_gemma_finetune_q4_k_m.gguf \
--model_id ../my_gemma_finetune \
--quantization_type Q4_K_M
quantization_type 选项非常关键,常见的量化类型包括:
F16(或FP16): 16位浮点数,无损或极低损耗,文件较大,推理较慢。Q8_0: 8位整数,文件大小减半,推理速度提升,性能损失极小。Q5_K_M: 5位混合量化,兼顾文件大小和性能,是常用选择。Q4_K_M: 4位混合量化,文件最小,推理最快,但性能损失可能稍大。
选择合适的量化类型需要在文件大小、推理速度和模型性能之间进行权衡。
11.5 模型卡与版本管理
随着模型开发周期的推进,有效的模型管理变得至关重要。
模型卡 (Model Card):
模型卡是一种结构化的文档,旨在提供关于模型的重要元数据和上下文信息。它通常包含:
- 模型名称与版本: 清晰标识模型。
- 开发者: 团队或个人信息。
- 发布日期: 模型发布时间。
- 模型架构: 使用的基座模型、微调方法(LoRA/QLoRA等)。
- 训练数据: 使用的训练数据集、数据来源、数据大小、任何预处理步骤。
- 预期用途: 模型设计用于解决什么问题,目标用户是谁。
- 限制与风险: 模型可能存在的偏见、局限性、不适合的应用场景。
- 评估结果: 详细的基准测试结果(如 MMLU、HellaSwag 分数),包括评估设置(few-shot/zero-shot)。
- 能耗: 训练和推理的估计能耗。
- 许可证: 模型和权重的许可协议。
为什么要创建模型卡?
- 透明度: 提高模型的透明度,帮助用户理解模型的能力和局限性。
- 负责任的 AI: 促进负责任的 AI 开发和部署。
- 可追溯性: 记录模型的关键信息,便于后续维护和审计。
- 沟通: 作为开发者、用户和利益相关者之间沟通的桥梁。
版本管理:
在模型开发和部署过程中,模型版本管理是必不可少的。
- Git LFS (Large File Storage): 对于模型权重这种大文件,标准的 Git 仓库管理效率低下。Git LFS 允许你在 Git 仓库中跟踪大文件,但实际文件内容存储在远程 LFS 服务器上,只在需要时下载。
- Hugging Face Hub: Hugging Face Hub 提供了一个强大的平台,用于托管、分享和版本化 LLM。你可以将微调后的 Gemma 模型直接上传到 Hub,它会自动处理大文件、提供模型卡模板、版本历史和社区互动功能。
- 上传流程:
- 安装
huggingface_hub库并登录:pip install huggingface_hub && huggingface-cli login - 创建一个新的仓库:
huggingface-cli repo create <your-model-name> --type model - 使用
push_to_hub方法:model.push_to_hub("your-org/your-model-name")
- 安装
- 上传流程:
最佳实践:
- 每次对模型进行重大更改(如更改数据集、超参数、架构)后,都应视为新版本并记录。
- 为每个版本创建清晰的标签或提交信息。
- 在模型卡中记录每个版本的详细信息,包括其评估结果。
💻 实战演示
11.6 实战一:使用 lm-evaluation-harness 评估微调后的 Gemma 模型
本实战将演示如何使用 lm-evaluation-harness 评估一个假设已经微调完成的 Gemma 模型。
前置条件:
- 您已经安装了
lm-evaluation-harness、transformers和torch。 - 您有一个微调后的 Gemma 模型,保存为 Hugging Face 格式,例如在
./my_gemma_finetune目录下。
步骤:
准备评估环境
确保所有依赖都已安装。
pip install lm-evaluation-harness transformers torch accelerate运行评估命令
我们将评估微调后的 Gemma 模型在
mmlu_stem和hellaswag任务上的表现。这里我们假设模型路径为./my_gemma_finetune,您需要将其替换为您的实际模型路径。# 注意:评估大型模型可能需要大量 GPU 内存和时间。 # 确保您的 GPU 能够加载模型并处理批量推理。 # 对于 Gemma 7B/27B,可能需要 A100 或 H100 GPU。 # 如果内存不足,请降低 --batch_size 或使用更小的模型。 LM_EVAL_DIR="./eval_results" MODEL_PATH="./my_gemma_finetune" # 替换为您的微调模型路径 mkdir -p $LM_EVAL_DIR lm_eval --model hf \ --model_args pretrained=$MODEL_PATH,trust_remote_code=True \ --tasks mmlu_stem,hellaswag \ --num_fewshot 0 \ --device cuda:0 \ --batch_size 4 \ --output_path $LM_EVAL_DIR/gemma_finetuned_eval.json \ --log_samples # 记录每个样本的预测结果pretrained=$MODEL_PATH: 指定加载本地微调模型。trust_remote_code=True: 如果您的模型使用了自定义代码(例如自定义层或分词器),则需要此参数。Gemma 模型通常不需要,但为了兼容性可以加上。--num_fewshot 0: 这里我们演示 Zero-shot 评估。在实际的 MMLU 评估中,通常使用 Few-shot (例如--num_fewshot 5) 来获得更具代表性的结果。
解读评估结果
评估完成后,结果将保存在
$LM_EVAL_DIR/gemma_finetuned_eval.json文件中。打开该文件,您会看到类似以下结构的 JSON 输出:{ "results": { "mmlu_stem": { "acc": 0.5567, "acc_stderr": 0.0123, "acc_norm": 0.5789, "acc_norm_stderr": 0.0125 }, "hellaswag": { "acc": 0.7891, "acc_stderr": 0.0034, "acc_norm": 0.7912, "acc_norm_stderr": 0.0033 } }, "versions": { "mmlu_stem": 0, "hellaswag": 0 }, "config": { // ... 评估配置信息 ... } }acc: 准确率 (accuracy)。acc_stderr: 准确率的标准误差,反映了结果的置信度。acc_norm: 归一化准确率 (normalized accuracy),对于某些任务,这可能更具代表性。
根据这些结果,您可以与原始 Gemma 模型或其他基准模型进行比较,判断微调的效果。例如,如果原始 Gemma 2B 在 MMLU 上的
acc是 40%,而您的微调模型达到了 55%,那么微调是成功的。
11.7 实战二:将微调后的 Gemma 模型导出为 GGUF 格式
本实战将演示如何将微调后的 Hugging Face 格式的 Gemma 模型转换为 GGUF 格式。
前置条件:
- 您已经克隆了
llama.cpp仓库并安装了其 Python 依赖。 - 您有一个微调后的 Gemma 模型,保存为 Hugging Face 格式,例如在
./my_gemma_finetune目录下。
步骤:
克隆
llama.cpp仓库并安装依赖git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp pip install -r requirements.txt执行 GGUF 转换
假设您的微调模型位于
../my_gemma_finetune(相对于llama.cpp目录)。我们将它转换为 Q4_K_M 量化版本。# 假设当前在 llama.cpp 目录下 MODEL_HF_PATH="../my_gemma_finetune" # 替换为您的微调模型路径 OUTPUT_GGUF_PATH="../my_gemma_finetune_q4_k_m.gguf" python convert.py --outfile $OUTPUT_GGUF_PATH \ --model_id $MODEL_HF_PATH \ --quantization_type Q4_K_M echo "GGUF 模型已导出到: $OUTPUT_GGUF_PATH"--model_id: 可以是 Hugging Face 模型 ID (例如google/gemma-2b) 或本地模型目录路径。--quantization_type: 指定量化类型。除了Q4_K_M,您还可以尝试F16(全精度)、Q8_0、Q5_K_M等。
转换过程可能需要一些时间,具体取决于模型大小和您的 CPU 性能。完成后,您将在指定路径得到一个
.gguf文件。
11.8 实战三:使用 Ollama 部署 GGUF 模型
Ollama 是一个轻量级的 LLM 运行环境,它使得在本地运行 GGUF 模型变得异常简单。
前置条件:
- 您已经安装了 Ollama。可以从 https://ollama.com/download 下载并安装。
- 您已经将微调后的 Gemma 模型导出为 GGUF 格式(如上一步骤)。
步骤:
准备 Modelfile
Ollama 使用
Modelfile来定义模型。创建一个名为Modelfile的文件(与您的 GGUF 模型在同一目录下,或者指定路径),内容如下:# Modelfile # 从你的 GGUF 模型文件导入 FROM ./my_gemma_finetune_q4_k_m.gguf # 设置模型参数 (可选) # TEMPLATE "{{ .Prompt }}" # PARAMETER temperature 0.7 # PARAMETER top_k 40 # PARAMETER top_p 0.9 # 设置模型描述 (可选) # MESSAGE system "你是一个专业的AI助手,擅长回答技术问题。" # 标签,用于识别模型 LABEL author "Your Name/Org" LABEL license "Apache 2.0" LABEL description "Fine-tuned Gemma for specific task X, quantized to Q4_K_M."FROM ./my_gemma_finetune_q4_k_m.gguf: 替换为您的 GGUF 模型的实际路径。TEMPLATE: Gemma 模型通常有特定的提示模板,可以根据需要设置。PARAMETER: 可以设置模型推理参数。LABEL: 添加元数据,便于识别和管理。
创建 Ollama 模型
在包含
Modelfile的目录下打开终端,执行以下命令:ollama create my-finetuned-gemma -f Modelfilemy-finetuned-gemma: 您为该模型指定的名称。
Ollama 会读取
Modelfile并将您的 GGUF 模型导入到其本地模型库中。运行 Ollama 模型
创建成功后,您就可以像运行任何其他 Ollama 模型一样运行您的微调 Gemma 模型了:
ollama run my-finetuned-gemma现在,您可以在终端中与您的微调 Gemma 模型进行交互了。
>>> How can I fine-tune a Gemma model? (Model responds based on its fine-tuned knowledge)您也可以通过 Ollama API 与模型交互,这使得将模型集成到应用程序中变得非常方便。
🔧 涉及的工具与命令
| 工具/命令 | 描述 | 示例用途 |
|---|---|---|
pip install lm-evaluation-harness |
安装 lm-evaluation-harness 评估框架。 |
pip install lm-evaluation-harness transformers torch accelerate |
lm_eval |
运行 lm-evaluation-harness 命令行工具进行模型评估。 |
lm_eval --model hf --model_args pretrained=./my_model --tasks mmlu_stem |
git clone |
克隆 llama.cpp 仓库,获取 GGUF 转换工具。 |
git clone https://github.com/ggerganov/llama.cpp.git |
python convert.py |
llama.cpp 提供的 Python 脚本,用于将 Hugging Face 模型转换为 GGUF 格式。 |
python convert.py --outfile model.gguf --model_id my_hf_model_path |
ollama create |
使用 Modelfile 将 GGUF 模型导入到 Ollama。 |
ollama create my-model -f Modelfile |
ollama run |
在 Ollama 中运行已导入的模型进行交互式推理。 | ollama run my-model |
huggingface-cli login |
登录 Hugging Face Hub,用于模型上传。 | huggingface-cli login |
model.push_to_hub() |
transformers 库中用于将模型上传到 Hugging Face Hub 的方法。 |
model.push_to_hub("your-org/your-gemma-finetune") |
📝 本期要点回顾
- 评估至关重要: 微调后的模型评估是开发流程中不可或缺的一环,它能客观量化模型的改进,避免过拟合,并指导后续优化。
lm-evaluation-harness是利器: 掌握lm-evaluation-harness框架,能够标准化地评估 Gemma 模型在各种基准测试上的性能,如