基于 Llama factory 微调 Llama3.1-70B-Chinese-Chat

​ 本文旨在探讨基于Llama factory使用LoRA(Low-Rank Adaptation)技术对Llama3.1-70B-Chinese-Chat模型进行微调的过程,重点介绍在单机多卡和多机多卡两种分布式训练环境下的实现方法。

1.环境准备

1.1 平台环境

微调Llama3.1-70B模型,本地环境跑不了。只能选择租用云上GPU。关于算力租赁平台,我选择的是FunHPC,理由如下:

  • 官网简单明了,进去就能租(无需排队),显卡类型多,总能找到适合我的卡型。
  • 价格非常亲民,和其他平台相比,算是非常便宜了。
  • 提供code-server开发界面,开发方便快捷。
  • 最近官方出了一个活动,只要发文章,就能领取80元的算力金。趁着这个机会,写一份我微调Llama3.1-70B的历程。

磁盘空间扩容:

  • 600G

显卡选择

  • 单机多卡训练选择的是8×A100(40G),即1台A100服务器。
  • 多机多卡训练选择的是2×8×100(40G),即2台A100服务器。

租用镜像选择:

  • pytorch 2.2.0+cuda121

1.2 Llama factory 环境

1.2.1 下载Llama factory
复制代码
git clone https://github.com/hiyouga/LLaMA-Factory.git
1.2.2 安装 Llama factory环境
复制代码
cd LLaMA-Factory
pip install -e ".[torch,metrics]"

2.数据集准备

下面的python代码主要完成3个方面:

  1. 配置代理,方便访问huggingface,这里我画上了下,不方便透露了。
  2. 从huggingface上下载m-a-p/COIG-CQIA数据集,作为本次微调的数据集。
  3. 将下载后的数据集,转换成Alpaca格式。

Alpaca格式如下:

复制代码
[
  {   
    "instruction": 
    "human instruction (required)",    
    "input": "human input (optional)",    
    "output": "model response (required)",    
    "system": "system prompt (optional)",    
    "history": [   
      ["human instruction in the first round (optional)", "model response in the first round (optional)"],      
      ["human instruction in the second round (optional)", "model response in the second round (optional)"]   
    ]
  }
]

import os
import json
from datasets import load_dataset, concatenate_datasets

# 设置代理
os.environ["http_proxy"] = "*****"
os.environ["https_proxy"] = "*****"

def prepare_data():
    data_names = ["chinese_traditional", "human_value", "wiki", "ruozhiba", "logi_qa", "wikihow", "zhihu", "douban", "xhs"]    
    datasets = [load_dataset("m-a-p/COIG-CQIA", name=name, cache_dir="./data", split="train") for name in data_names]    
    concatenated_dataset = concatenate_datasets(datasets)    
    return concatenated_dataset

def convert_to_alpaca_format(dataset):
    alpaca_data = []   
    for entry in dataset:    
        alpaca_entry = {       
            "instruction": entry['instruction'],            
            "input": entry['input'],            
            "output": entry['output']        
        }        
        alpaca_data.append(alpaca_entry)    
    return alpaca_data

# 准备数据并转换为 Alpaca 格式
datasets = prepare_data()
alpaca_data = convert_to_alpaca_format(datasets)

# 将结果保存为 JSON 文件,不转义非 ASCII 字符
with open('alpaca_format_data.json', 'w', encoding='utf-8') as f: 
    json.dump(alpaca_data, f, ensure_ascii=False, indent=4)

print("转换完成,数据已保存为 'alpaca_format_data.json'")

3.模型准备

3.1 模型下载

复制代码
pip install modelscope
modelscope download --model XD_AI/Llama3.1-70B-Chinese-Chat --local_dir /data/coding/Llama3.1-70B-Chinese-Chat

3.2 模型校验

由于model比较大,会报显存错误。我将校验代码修改了一下,改成多卡调用。

复制代码
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

model_id = "/data/coding/Llama3.1-70B-Chinese-Chat"
dtype = torch.bfloat16

# 加载 tokenizer
tokenizer = AutoTokenizer.from_pretrained(model_id)

# 设置 pad_token_id
pad_token_id = tokenizer.pad_token_id if tokenizer.pad_token_id is not None else tokenizer.eos_token_id

# 使用 device_map 自动将模型切分到多 GPU
model = AutoModelForCausalLM.from_pretrained(
    model_id,    
    torch_dtype=dtype,    
    device_map="auto"
)

chat = [{"role": "user", "content": "写一首关于机器学习的诗。"}]
inputs = tokenizer.apply_chat_template(chat, tokenize=True, add_generation_prompt=True, return_tensors="pt")

# 设置 attention_mask
input_ids = inputs.input_ids.to("cuda:0")
attention_mask = inputs.attention_mask.to("cuda:0") if "attention_mask" in inputs else None

# 推理
outputs = model.generate(
    input_ids,    
    attention_mask=attention_mask,  # 添加 attention_mask    
    max_new_tokens=8192,    
    do_sample=True,    
    temperature=0.6,    
    top_p=0.9,    
    pad_token_id=pad_token_id  # 设置 pad_token_id
)

response = outputs[0][input_ids.shape[-1]:]
print(tokenizer.decode(response, skip_special_tokens=True))

输出结果:

4.模型训练

在训练之前需要做的两件事儿:

    • 将alpaca_format_data.json文件放到Llama factory的data目录下。

    • 在dataset_info.json中添加:

      {

      "alpaca_format_data": {

      "file_name": "alpaca_format_data.json"

      },

4.1 单机多卡训练

我的llama3_lora_sft_ds31.yaml如下:

终端执行命令如下:

复制代码
FORCE_TORCHRUN=1 llamafactory-cli train /data/coding/LLaMA-Factory/examples/train_lora/llama3_lora_sft_ds31.yaml

训练过程如下:

复制代码
[INFO|trainer.py:2134] 2024-08-16 09:14:59,763 >> ***** Running training *****
[INFO|trainer.py:2135] 2024-08-16 09:14:59,763 >>   Num examples = 22,582
[INFO|trainer.py:2136] 2024-08-16 09:14:59,763 >>   Num Epochs = 5
[INFO|trainer.py:2137] 2024-08-16 09:14:59,763 >>   Instantaneous batch size per device = 8
[INFO|trainer.py:2140] 2024-08-16 09:14:59,763 >>   Total train batch size (w. parallel, distributed & accumulation) = 512
[INFO|trainer.py:2141] 2024-08-16 09:14:59,763 >>   Gradient Accumulation steps = 8
[INFO|trainer.py:2142] 2024-08-16 09:14:59,763 >>   Total optimization steps = 220
[INFO|trainer.py:2143] 2024-08-16 09:14:59,774 >>   Number of trainable parameters = 103,546,880

{'loss': 2.021, 'grad_norm': 0.31445133686065674, 'learning_rate': 0.00022727272727272727, 'epoch': 0.23}                                                                               
{'loss': 1.7366, 'grad_norm': 0.13742084801197052, 'learning_rate': 0.00045454545454545455, 'epoch': 0.45}                                                                                    
{'loss': 1.6267, 'grad_norm': 0.06480135023593903, 'learning_rate': 0.0004979887032076989, 'epoch': 0.68}                                                                                         
{'loss': 1.5846, 'grad_norm': 0.05686546117067337, 'learning_rate': 0.0004898732434036243, 'epoch': 0.91}                                                                                         
{'loss': 1.5642, 'grad_norm': 0.05606243386864662, 'learning_rate': 0.0004757316345716554, 'epoch': 1.13}                                                                                         
{'loss': 1.5164, 'grad_norm': 0.06566128134727478, 'learning_rate': 0.0004559191453574582, 'epoch': 1.36}                                                                                         
{'loss': 1.5104, 'grad_norm': 0.06976603716611862, 'learning_rate': 0.0004309335095262675, 'epoch': 1.59}                                                                                         
{'loss': 1.4946, 'grad_norm': 0.06345170736312866, 'learning_rate': 0.00040140242178441667, 'epoch': 1.81}                                                                                        
{'loss': 1.4851, 'grad_norm': 0.07551503926515579, 'learning_rate': 0.0003680677686931707, 'epoch': 2.04}                                                                                         
{'loss': 1.4064, 'grad_norm': 0.11773069202899933, 'learning_rate': 0.00033176699082935546, 'epoch': 2.27}                                                                                        
{'loss': 1.411, 'grad_norm': 0.09556800872087479, 'learning_rate': 0.00029341204441673266, 'epoch': 2.49}                                                                                         
{'loss': 1.4018, 'grad_norm': 0.09359253197908401, 'learning_rate': 0.000253966490958702, 'epoch': 2.72}                                                                                          
{'loss': 1.3875, 'grad_norm': 0.1037076786160469, 'learning_rate': 0.00021442129043167875, 'epoch': 2.95}                                                                                         
{'loss': 1.3314, 'grad_norm': 0.12813276052474976, 'learning_rate': 0.00017576990616793137, 'epoch': 3.17}                                                                                        
{'loss': 1.3125, 'grad_norm': 0.1260678470134735, 'learning_rate': 0.00013898334684855646, 'epoch': 3.4}                                                                                          
{'loss': 1.2788, 'grad_norm': 0.13497693836688995, 'learning_rate': 0.00010498577260720049, 'epoch': 3.63}                                                                                        
{'loss': 1.2677, 'grad_norm': 0.12839122116565704, 'learning_rate': 7.463127807341966e-05, 'epoch': 3.85}                                                                                         
{'loss': 1.2469, 'grad_norm': 0.175085186958313, 'learning_rate': 4.8682435617235344e-05, 'epoch': 4.08}                                                                                          
{'loss': 1.2235, 'grad_norm': 0.1542418748140335, 'learning_rate': 2.7791137836269158e-05, 'epoch': 4.31}                                                                                         
{'loss': 1.1948, 'grad_norm': 0.14159728586673737, 'learning_rate': 1.2482220564763668e-05, 'epoch': 4.53}                                                                                        
{'loss': 1.2039, 'grad_norm': 0.13814429938793182, 'learning_rate': 3.1402778309014278e-06, 'epoch': 4.76}                                                
{'loss': 1.2098, 'grad_norm': 0.13053908944129944, 'learning_rate': 0.0, 'epoch': 4.99} 

{'train_runtime': 88370.9016, 'train_samples_per_second': 1.278, 'train_steps_per_second': 0.002, 'train_loss': 1.4279815023595637, 'epoch': 4.99}   

[INFO|trainer.py:3821] 2024-08-17 09:50:24,508 >>   Num examples = 2510
[INFO|trainer.py:3824] 2024-08-17 09:50:24,508 >>   Batch size = 8
100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 40/40 [14:59<00:00, 22.49s/it]
***** eval metrics *****
  epoch                   =     4.9858  
  eval_loss               =     1.5017  
  eval_runtime            = 0:15:24.41  
  eval_samples_per_second =      2.715  
  eval_steps_per_second   =      0.043

训练时间大致:15小时

显卡占用如下:

训练loss如下:

4.2 多机多卡训练

训练的yaml文件和单机多卡一致。

终端执行命令如下:

主节点:

复制代码
FORCE_TORCHRUN=1 NNODES=2 RANK=0 MASTER_ADDR=10.222.51.150 MASTER_PORT=29500 llamafactory-cli train /data/coding/LLaMA-Factory/examples/train_lora/llama3_lora_sft_ds31.yaml

次节点:

复制代码
FORCE_TORCHRUN=1 NNODES=2 RANK=1 MASTER_ADDR=10.222.51.150 MASTER_PORT=29500 llamafactory-cli train /data/coding/LLaMA-Factory/examples/train_lora/llama3_lora_sft_ds31.yaml

训练时间大致:63小时

复制代码
{'loss': 1.9696, 'grad_norm': 0.10808725655078888, 'learning_rate': 0.00045454545454545455, 'epoch': 0.45}                                                                                         
13%|██████████████████▋                                            | 14/110 [22:44:00<155:12:34, 5820.36s/it

由于这里训练时间较长,就不展示训练过程及训练loss。

5.模型效果展示

复制代码
CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 llamafactory-cli chat  --model_name_or_path /data/coding/Llama3.1-70B-Chinese-Chat  --adapter_name_or_path /data/coding/LLaMA3-70B/lora/sft --template llama3 --finetuning_type lora

推理效果如下:

复制代码
User: 为什么昙花开花时间非常短?
Assistant: 昙花原产于南美洲墨西哥、危地马拉、委内瑞拉等热带地区。昙花的花朵非常美丽,花朵颜色有红色、白色、紫色、粉红色、黄色等。它的花朵大多数在晚上开,第二天早晨就凋谢了,因此它又叫"一夜夫人"、"夜合花"等。昙花的花朵为什么时间这么短呢?原来昙花是喜暖的植物,白天温度高时,花瓣的伸展能力变弱,不能正常地舒展开来;而到了晚上温度低时,花瓣的伸展能力增强,花朵就开放了。到了第二天早晨,气温升高,花瓣的伸展能力又减弱,花朵便慢慢地合拢,最后就枯萎凋谢了。昙花的花朵时间短是由它的生理特性决定的。

User: 为什么英国曾被称为"日不落帝国"?
Assistant: 英国曾被称为"日不落帝国",这是因为在18世纪和19世纪的殖民战争中,英国占领了世界各地的许多地方,从而建立了一个庞大的殖民帝国。当时英国在世界各地的殖民地非常多,无论什么时候,英国总有地方是白天。英国的这种特殊地位使它在当时被称为"日不落帝国"。但是,随着时间的推移,英国的殖民地逐渐独立,英国的殖民地数量也在不断减少,最终英国的殖民地几乎全部独立,英国的"日不落帝国"也随之消失了。

User: 给我介绍一下算力显卡
Assistant: 算力显卡是指那些专门用于计算的显卡。这些显卡通常具有非常高的性能和非常低的功耗,它们可以帮助用户进行各种复杂的计算任务,如数据挖掘、机器学习等。算力显卡的主要特点是它们具有非常高的浮点运算能力,这使得它们可以快速地处理大量的数据并产生高质量的结果。此外,算力显卡还具有非常低的功耗,这使得它们可以在长时间的运行中保持稳定的性能。

6.总结

​ 本文通过单机多卡和多机多卡的情况下,完成基于Llama factory使用LoRA(Low-Rank Adaptation)技术对Llama3.1-70B-Chinese-Chat模型进行微调的过程。总体的推理效果不错。对于多机多卡下,训练速度慢的问题还有待改善。

如何学习AI大模型?

作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

一、全套AGI大模型学习路线

AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

三、AI大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

四、AI大模型商业化落地方案

作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量。

相关推荐
AI科技星7 小时前
全域谱分析:无穷维超复数信息场分形统一场论 ——自然、量子、金融多重分形第一性原理完整体系(中英双语终稿)
人工智能·机器学习·金融·乖乖数学·全域数学
stormzhangV7 小时前
为什么你的 AI 像智障
人工智能
Jerry7 小时前
LeetCode 383. 赎金信
算法
ai产品老杨8 小时前
H264 H265视频分析常见问题和排查清单
人工智能·算法·音视频
项目经理老王8 小时前
OpenClaw无捆绑安装包,安全纯净版AI助手部署
人工智能·安全
Jerry8 小时前
LeetCode 454. 四数相加 II
算法
梦帮科技8 小时前
GRAVIS v4.0:基于Web的极速套利架构设计与实时数据流实现
前端·人工智能·rust·自动化·区块链·智能合约·数字货币
“码”力全开8 小时前
AI视频分析API性能优化指南
人工智能·性能优化·音视频
liuyicenysabel9 小时前
大模型学习笔记 · 第八篇 · 进阶:偏好对齐与多卡训练
人工智能·笔记·学习
可编程芯片开发9 小时前
基于CPS-SPWM链式STATCOM系统在电压不平衡环境下控制策略的simulink建模与仿真
算法