欺诈文本分类检测(十一):LLamaFactory多卡微调

打印 上一主题 下一主题

主题 1810|帖子 1810|积分 5430

1. 弁言

前文练习时都做了一定的编码工作,其实有一些框架可以支持我们零代码微调,LLama-Factory就是此中一个。这是一个专门针对大语言模型的微调和练习平台,有如下特性:


  • 支持常见的模型种类:LLaMA、Mixtral-MoE、Qwen、Baichuan、ChatGLM等等。
  • 支持单GPU和多GPU练习。
  • 支持全参微调、Lora微调、QLora微调。
    ……
   另有许多良好的特性,详细参考:https://llamafactory.readthedocs.io/zh-cn/latest/
  本文会实验用LLamaFactory举行一次多GPU练习。
2. 安装

  1. git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git
  2. cd LLaMA-Factory
  3. pip install -e ".[torch,metrics,deepspeed,bitsandbytes,vllm]"
复制代码
安装完后实验llamafactory-cli version验证安装是否成功,结果报了AttributeError: module 'torch.library' has no attribute 'register_fake'。

原因:PyTorch 和 TorchVision 版本不兼容,经常发生在torchvision较新而pytorch版本较旧的场景。
解法:使用pip install --upgrade torch torchvision 更新两者版本使之一致,再次运行llamafactory-cli version后正常输出了版本号0.8.4。
  1. ----------------------------------------------------------
  2. | Welcome to LLaMA Factory, version 0.8.4.dev0           |
  3. |                                                        |
  4. | Project page: https://github.com/hiyouga/LLaMA-Factory |
  5. ----------------------------------------------------------
复制代码
3. 数据处理

针对sft, llamafactory支持多种数据格式,我们这里选用alpaca,此格式简单清晰,每条数据只需包罗三个字段:


  • instruction 列对应的内容为人类指令;
  • input 列对应的内容为人类输入;
  • output 列对应的内容为模型回答。
  1. {
  2.   "instruction": "计算这些物品的总费用。 ",
  3.   "input": "输入:汽车 - $3000,衣服 - $100,书 - $20。",
  4.   "output": "汽车、衣服和书的总费用为 $3000 + $100 + $20 = $3120。"
  5. },
复制代码
为了格式匹配,封装一个函数to_alpaca用于转换数据。
  1. import json  
  2. def to_alpaca(input_path, output_path):
  3.     with open(input_path, 'r', encoding='utf-8') as infile, open(output_path, 'w', encoding='utf-8') as outfile:  
  4.         dataset = []
  5.         for line in infile:  
  6.             data = json.loads(line)  
  7.             item = {
  8.                 'input': data['input'],
  9.                 'output': json.dumps({'is_fraud':data['label']}, ensure_ascii=False),
  10.                 'instruction':data['instruction'],
  11.             }  
  12.             dataset.append(item)
  13.         # 将结果写入输出文件  
  14.         outfile.write(json.dumps(dataset, indent=4, ensure_ascii=False))  
  15.         print(f"convert over,{input_path} to {output_path}")
复制代码
批量将前文欺诈文本分类微调(四):构造练习/测试数据集已经构建好的数据集作格式转换。
  1. input_files = [
  2.     '../dataset/fraud/train_test/train0819.jsonl',
  3.     '../dataset/fraud/train_test/test0819.jsonl',
  4.     '../dataset/fraud/train_test/eval0819.jsonl',
  5. ]
  6. for input_path in input_files:
  7.     output_path = f'../dataset/fraud/train_test/{filename(input_path)}_alpaca.json'
  8.     to_alpaca(input_path, output_path)
复制代码
  1. convert over,../dataset/fraud/train_test/train0819.jsonl to ../dataset/fraud/train_test/train0819_alpaca.json
  2. convert over,../dataset/fraud/train_test/test0819.jsonl to ../dataset/fraud/train_test/test0819_alpaca.json
  3. convert over,../dataset/fraud/train_test/eval0819.jsonl to ../dataset/fraud/train_test/eval0819_alpaca.json
复制代码
文件内容如下所示:
  1. [
  2.     {
  3.         "input": "发言人3: 现在我所在这个哪里能够工艺能够去把屈光做得很好的,去到这个省级医院是自治区医院跟广西医科大学这个附属医院他们还可以,他们一直保持比较好的一个一个手术量。\n发言人1: 就是",
  4.         "output": "{"is_fraud": false}",
  5.         "instruction": "\n下面是一段对话文本, 请分析对话内容是否有诈骗风险,以json格式输出你的判断结果(is_fraud: true/false)。\n"
  6.     },
  7.     ……
  8.     {
  9.         "input": "发言人12: 好的,感谢大家参加本次电话会议会议到此结束,祝大家生活愉快,再见。\n发言人1: 本次会议已结束。\n发言人2: the meeting has ended。",
  10.         "output": "{"is_fraud": false}",
  11.         "instruction": "\n下面是一段对话文本, 请分析对话内容是否有诈骗风险,以json格式输出你的判断结果(is_fraud: true/false)。\n"
  12.     }
  13. ]
复制代码
转换好数据集后,需要将其配置到LLamaFactory安装目次下的data/dataset_info.json文件中,只需要在文件末了添加我们新构造的数据集。
  1. {
  2.   "identity": {
  3.     "file_name": "identity.json"
  4.   },
  5.   ……
  6.   "anti_fraud": {
  7.     "file_name": "train0819_alpaca.jsonl",
  8.     "columns": {
  9.       "prompt": "instruction",
  10.       "query": "input",
  11.       "response": "output"
  12.     }
  13.   }
  14. }
复制代码
4. 练习参数配置

LLamaFactory的练习参数采用yaml文件保存,在安装目次下的examples子目次下有各种微调方法的示例配置,可以直接拷贝一份举行修改。

yaml文件中采用分块配置,下面分别示例。
模型路径

  1. ### model
  2. model_name_or_path: /data2/anti_fraud/models/modelscope/hub/Qwen/Qwen2-1___5B-Instruct
复制代码
微调方法

说明:同前面练习的参数配置保持一致。
  1. stage: sft         
  2. do_train: true
  3. finetuning_type: lora  # 具体微调方法采用Lora
  4. lora_target: q_proj,k_proj,v_proj,o_proj,gate_proj,up_proj,down_proj
  5. lora_rank: 16
  6. lora_alpha: 32
  7. lora_dropout: 0.2
复制代码


  • stage: sft :LLamaFactory中将练习分别成了许多阶段,例如:rm(reward modeling), pt(pretrain), sft(Supervised Fine-Tuning), PPO, DPO, KTO, ORPO,监视微调选择sft。
  • finetuning_type: lora 微调方法选择Lora。

数据集配置

这部分参数界说上有些差别,下面会详细说明。
  1. dataset: anti_fraud
  2. template: qwen
  3. cutoff_len: 2048
  4. max_samples: 200000
  5. overwrite_cache: true
  6. preprocessing_num_workers: 16
复制代码
dataset: anti_fraud 是用于上面在dataset_info.json中添加的数据集名称。
template: llama3 此参数控制着终极给模型练习的数据模板。


  • 如果是llama3:
  1. <|start_header_id|>user<|end_header_id|>
  2. 下面是一段对话文本, 请分析对话内容是否有诈骗风险,以json格式输出你的判断结果(is_fraud: true/false)。
  3. 发言人3: 现在我所在这个哪里能够工艺能够去把屈光做得很好的,去到这个省级医院是自治区医院跟广西医科大学这个附属医院他们还可以,他们一直保持比较好的一个一个手术量。
  4. 发言人1: 就是<|eot_id|><|start_header_id|>assistant<|end_header_id|>
  5. {"is_fraud": false}<|eot_id|>
复制代码


  • 如果是qwen:
  1. <|im_start|>system
  2. You are a helpful assistant.<|im_end|>
  3. <|im_start|>user
  4. 下面是一段对话文本, 请分析对话内容是否有诈骗风险,以json格式输出你的判断结果(is_fraud: true/false)。
  5. 发言人3: 现在我所在这个哪里能够工艺能够去把屈光做得很好的,去到这个省级医院是自治区医院跟广西医科大学这个附属医院他们还可以,他们一直保持比较好的一个一个手术量。
  6. 发言人1: 就是<|im_end|>
  7. <|im_start|>assistant
  8. {"is_fraud": false}<|im_end|>
复制代码
cutoff_len: 相称于max_length,限制一条数据的最大长度,超出截断。
max_samples: 用于限制在练习或评估过程中使用的样本数目。此参数重要实用于数据集非常大并且不需要所有样本都举行练习的场景。
输出配置

说明:同前面练习的参数配置保持一致。
  1. ### output
  2. output_dir: /data2/anti_fraud/models/Qwen2-1___5B-Instruct_ft_0826
  3. logging_steps: 10
  4. save_steps: 100
  5. plot_loss: true
  6. overwrite_output_dir: true
复制代码
练习配置

说明:同前面练习的参数配置保持一致。
  1. per_device_train_batch_size: 16
  2. gradient_accumulation_steps: 1
  3. gradient_checkpointing: true
  4. learning_rate: 1.0e-4
  5. num_train_epochs: 3.0
  6. lr_scheduler_type: cosine
  7. warmup_ratio: 0.05
  8. bf16: true
  9. ddp_timeout: 180000000
复制代码
验证配置

说明:同前面练习的参数配置保持一致。
  1. val_size: 0.1
  2. per_device_eval_batch_size: 8
  3. eval_strategy: steps
  4. eval_steps: 100
复制代码
配置完成后,将上面的配置保存到qwen2_lora_sft.yaml 文件中。
5. 练习

5.1 开始练习

设置情况变量CUDA_VISIBLE_DEVICES声明练习过程中允许使用4张显卡,显卡编号分别为1、2、3、4。
使用 llamafactory-cli下令启动练习。
  1. export CUDA_VISIBLE_DEVICES=1,2,3,4
  2. llamafactory-cli train /data2/downloads/LLaMA-Factory/qwen2_lora_sft.yaml
复制代码
练习关键信息:
  1. 08/26/2024 18:08:49 - INFO - llamafactory.model.loader - trainable params: 18,464,768 || all params: 1,562,179,072 || trainable%: 1.1820
  2. [INFO|trainer.py:2134] 2024-08-26 18:08:50,496 >> ***** Running training *****
  3. [INFO|trainer.py:2135] 2024-08-26 18:08:50,496 >>   Num examples = 19,021
  4. [INFO|trainer.py:2136] 2024-08-26 18:08:50,496 >>   Num Epochs = 3
  5. [INFO|trainer.py:2137] 2024-08-26 18:08:50,496 >>   Instantaneous batch size per device = 16
  6. [INFO|trainer.py:2140] 2024-08-26 18:08:50,496 >>   Total train batch size (w. parallel, distributed & accumulation) = 64
  7. [INFO|trainer.py:2141] 2024-08-26 18:08:50,496 >>   Gradient Accumulation steps = 1
  8. [INFO|trainer.py:2142] 2024-08-26 18:08:50,496 >>   Total optimization steps = 894
  9. [INFO|trainer.py:2143] 2024-08-26 18:08:50,502 >>   Number of trainable parameters = 18,464,768
复制代码
  从上面这个信息可以看出一个显著变化,实际的批量大小batch_size从单卡下的16变成了多GPU下的64。在数据量不变的情况下,总的练习步数从之前的3522缩小到了894,相称于练习步数变少,而每一步迈的更大。
  第一个100步的信息:

练习完的eval_loss为0.0152,比单卡时的验证损失0.016190要低。
  1. ***** eval metrics *****
  2.   epoch                   =        3.0
  3.   eval_loss               =     0.0152
  4.   eval_runtime            = 0:00:17.00
  5.   eval_samples_per_second =    124.291
  6.   eval_steps_per_second   =      3.939
复制代码
5.2 可视化练习结果

使用tensorboard可视化练习过程中的数据指标。
  1. tensorboard --host=0.0.0.0 --port 6006 --logdir=/data2/anti_fraud/models/Qwen2-1___5B-Instruct_ft_0826/runs/Aug26_18-07-16_ubuntu/
复制代码
练习损失下降曲线:

验证损失下降曲线:

学习率变化曲线:

   学习率先降后升是学习率调度器配置lr_scheduler_type: cosine所起的作用,它将我们预设的1e-4作为最大值,刚开始练习时从2e-5左右迟钝上升至1e-4来适应数据,随着练习到了后期,渐渐降低学习率来实验找到损失最低点。
  5.3 评估测试

使用邪术下令%run导入评估脚本,界说原始模型/微调checkpoint的路径以及评估数据集。
  1. %run evaluate.py
  2. device = 'cuda'
  3. evaldata_path = '/data2/anti_fraud/dataset/eval0819.jsonl'
  4. model_path = '/data2/anti_fraud/models/modelscope/hub/Qwen/Qwen2-1___5B-Instruct'
  5. checkpoint_path_900 = '/data2/anti_fraud/models/Qwen2-1___5B-Instruct_ft_0826/checkpoint-900'
复制代码
运行评测:
  1. evaluate(model_path, checkpoint_path_900, evaldata_path, device, batch=True, debug=True)
复制代码
  1. progress: 100%|██████████| 2348/2348 [03:22<00:00, 11.59it/s]
  2. tn:1160, fp:5, fn:103, tp:1080
  3. precision: 0.9953917050691244, recall: 0.9129332206255283
复制代码
精确率precision从0.978上升到了0.995,召回率从0.866上升到了0.912,说明多张卡一起练习带来的批量大小增长,有助于模型更好的学习数据分布,从而更快的收敛到更优的解。
小结:本文实验用LLamaFactory工具对前面的欺诈文本分类任务举行了SFT微调练习,并启用了多张GPU,多GPU的直接影响是批量大小batch_size的4倍增长,使得模型每次练习时能看到更多的数据,举行更稳定梯度估计和更正确的参数更新,终极在评测指标上有一个显著的提拔。
参考文章



  • 欺诈文本分类微调(七):lora单卡二次调优
  • LLamaFactory使用教程
  • llama-factory参数体系
  • llama-factory微调参数详解

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

大连密封材料

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表