如何使用 Llama 3.2 1B 微调来替代 GPT-4o

更新时间:2024/11/07, 13:06

微调的效果是否优于少量提示?

作者使用 Flux.1.1-pro 创作的图片

如果问一个年轻的儿科医生和一位资深内科医生,谁更擅长治疗婴儿咳嗽?虽然二者都具备治疗儿童咳嗽的资质,但显然儿科医生会更专长于婴儿病症的诊断。

这就是微调对小模型的影响:它使较小、相对弱小的模型能在特定任务上胜过那些通用的大模型。

最近,我就遇到了这种选择的场景。

我在开发一个查询路由机器人,用于将用户的查询转发到正确的部门,之后由该部门的人工代理继续对话。背后其实是一个简单的文本分类任务。

GPT-4o 及其迷你版本在此任务上表现优秀,但同时它们既昂贵又僵化。而且它是一个封闭模型,无法在本地环境中进行微调。虽然 OpenAI 提供了微调服务,但费用不菲。

在 OpenAI 平台上训练 GPT-4o 每 100 万个 Token 成本高达 25 美元。我的训练数据很快达到了数百万 Token。更进一步,微调后的模型使用成本比原始模型高出约 50%

如此高的成本对我的小型应用来说难以承受,我的项目资金有限,必须考虑更具性价比的替代方案。

备选方案是使用开源模型。开源模型在分类任务中表现不错,但训练所需的大量 GPU 资源也是一笔不小的开销。

我最终决定尝试小型模型。

小型语言模型是微调的理想对象,能够在成本上取得平衡并实现良好效果。小模型不仅可以在更廉价的硬件上运行,还可以使用更经济的 GPU 进行微调。此外,它们的训练和推理速度要比大型语言模型快得多。

候选模型包括 Phi3.5、DistillBERT 和 GPT-Neo 等。我最终选择了 Meta 的 Llama 3.2 的 1B 模型,也许是受到了最近的讨论和推广的影响。

如果你托管大语言模型,服务器能承受多大压力?

本文将对比微调的 Llama 3.2–1B 模型与少量提示的 GPT-4o 在任务中的表现。

这是我的训练流程和成果。

微调 Llama 3.2 1B(无费用)

微调的成本较高,除非选择适当策略。你可以重新训练全部参数、迁移学习或参数高效微调。

  • 全参数训练是最贵的选择,会重新训练模型中的所有 10 亿参数,费时费钱。此外,全参数微调可能会导致“灾难性遗忘”,即模型可能会遗失预训练阶段学到的一些知识。
  • 迁移学习是个不错的选择,但稍显复杂。

迁移学习:深度学习中最高效的技能。

  • **参数高效微调(PEFT)既便宜又高效。这个策略只微调部分参数,其中低秩适应(LORA)**被认为是最佳选择。LORA 仅微调特定层中的一些参数,既能快速训练又能保持效果。

为了减少训练资源需求,我采用了量化。通过量化,可以将模型参数存储为 float16 或更小的数据类型,内存占用更小,计算速度更快,不过可能会略微影响准确性。

既然决定采用 LORA 进行微调,那么如何获取免费的训练资源呢?

Colab 或 Kaggle 笔记本提供免费的 GPU,通常足以用于小模型的微调。

微调的 Llama-3.2 对比少量提示的 OpenAI GPT-4o

LORA 微调已相当流行,这里不赘述教程。

可以参考 Unsloth 的 Colab 笔记本,它提供了详细的分步指导,我的微调任务也是基于该笔记本完成的。

以下是我的调整:

笔记本原本微调的是 Llama-3.2 3B 参数模型。如果这个模型适合你,可以保持不变,否则可以在多个可用模型中选择。我将其更改为 Llama-3.2–1B-Instruct,想测试小模型是否足以完成我的任务。

其次,需将数据集格式转换为微调所需的格式。我使用了自己的微调数据集,如下所示:

# 原代码
from unsloth.chat_templates import standardize_sharegpt
dataset = standardize_sharegpt(dataset)
dataset = dataset.map(formatting_prompts_func, batched=True,)

# 修改后
from datasets import Dataset
dataset = Dataset.from_json("/content/insurance_training_data.json")
dataset = dataset.map(formatting_prompts_func, batched=True,)

数据集结构可以简单定义为以下格式:

{
    "conversations": [
        {"role": "user", "content": "<user_query>"},
        {"role": "assistant", "content": "<department>"}
    ]
}

评估微调模型

LLM 评估是一个广泛且实用的领域。这里我采用经典的混淆矩阵方式进行评估。

在笔记本末尾添加以下代码:

from langchain.prompts import FewShotPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate
from pydantic import BaseModel

# 1. 使用微调模型生成响应
def generate_response(user_query):
    # 启用更快推理
    FastLanguageModel.for_inference(model)

    # 定义消息模板
    messages = [
        {"role": "system", "content": "You are a helpful assistant who can route the following query to the relevant department."},
        {"role": "user", "content": user_query},
    ]

    tokenized_input = tokenizer.apply_chat_template(
        messages, tokenize=True, add_generation_prompt=True, return_tensors="pt"
    ).to("cuda")

    generated_output = model.generate(
        input_ids=tokenized_input, max_new_tokens=64, use_cache=True, temperature=1.5, min_p=0.1
    )

    decoded_response = tokenizer.batch_decode(generated_output, skip_special_tokens=True)[0]
    assistant_response = decoded_response.split("\n\n")[-1]

    return assistant_response

# 2. 使用 OpenAI GPT-4o 生成响应
class Department(BaseModel):
    department: str

def predict_department(user_query):
    structured_llm = llm.with_structured_output(Department)
    prediction_chain = few_shot_prompt_template | structured_llm
    result = prediction_chain.invoke(user_query)
    return result.department

# 3. 读取评估数据集并预测部门
import json
with open("/content/insurance_bot_evaluation_data.json", "r") as f:
    eval_data = json.load(f)

for ix, item in enumerate(eval_data):
  print(f"{ix+1} of {len(eval_data)}")
  item['open_ai_response'] = generate_response(item['user_query'])
  item['llama_response'] = item['open_ai_response']

# 4. 计算预测的精度、召回率、准确率和 F1 分数。

# 4.1 使用 Open AI
from sklearn.metrics import precision_score, recall_score, accuracy_score, f1_score```yaml
OpenAI 响应评分:
精确度:0.9
召回率:0.75
准确率:0.75
F1 分数:0.818

Llama 响应评分:
精确度:0.88
召回率:0.73
准确率:0.79
F1 分数:0.798

结果显示微调后的 Llama-3.2 与 GPT-4o 在表现上非常接近,对于只有 10 亿参数的小模型来说,这是非常令人满意的成绩。

当然,GPT-4o 表现略胜一筹,但差距并不大。

我们可以在少量提示中提供更多示例以提升 GPT-4o 的效果,但这会增加成本,因为 OpenAI 按输入标记收费。

总结

我逐渐倾向于使用小型语言模型。它们不仅速度快、成本低,还能满足大多数实际需求,尤其是在微调后。

本文中,我展示了如何微调 Llama 3.2 1B 模型

,这是一个可在低成本硬件上运行的小型模型,非常适合文本分类任务。虽然小模型无法与 GPT-4o 或 Meta Llama 的 80 亿、110 亿和 900 亿参数模型的能力媲美,但对于不涉及多语言理解、视觉指引等复杂任务的应用场景,小模型已经足够。

如果这些高级功能并非必需,为何不尝试一个轻量且高效的小型大语言模型呢?

AI奇想空间
AI奇想空间
https://aimazing.site
AI 奇想空间是一个汇聚人工智能工具、资源和教程的导航网站。 在这里,你可以发现最新的AI技术、工具和应用,学习如何使用各种 AI 平台和框架,获取丰富的 AI 资源。 欢迎广大 AI 爱好者加入我们的社区,开启你的AI之旅!
AI交流群
Copyright © 2024 AI奇想空间.微信