小白教程:Unsloth 打造属于自己的中文版Llama3

打印 上一主题 下一主题

主题 1987|帖子 1987|积分 5961

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

x
在定制化业务场景中,假如使用专属数据集,经过微调的大模型能够在多种任务上与GPT-4媲美,并支持本地摆设,保护隐私,同时还能降低运算本钱。最新推出的Llama3,作为当前性能最强的开源基础大模型,非常实用于自然语言处置惩罚、呆板翻译、文本生成、问答体系、谈天呆板人等多种应用场景。
通过微调这一技术,基础大模型如Llama3即使原生不支持中文,也能增长对中文的支持。本教程将展示怎样使用LooPIN提供的GPU算力,从零开始为大模型添加新的训练素材,拓展其在原有能力基础上的新大概性。
准备工作

本教程将引导你怎样设置环境、准备数据、训练模型、摆设模型及生存模型。在8G显存的显卡上微调只需不到2分钟,且微调后的模型能被量化为4bit,在CPU上本地进行流畅的谈天推理。
我们将使用以下开源代码库:
Unsloth开源微调LLM工具

Unsloth: Github地址 - Unsloth GitHub
Unsloth是一款集成的模型微调工具。使用Unsloth微调Mistral、Gemma、Llama时,速率可提高2-5倍,内存使用可镌汰70%!
中文指令数据集

尽管LLM在中文指令调优方面还有不少进步空间,现有的数据集要么以英语为主,要么不适合现实中的中国用户交互模式。
为解决这一问题,由10家机构联合发布的研究提出了COIG-CQIA(全称Chinese Open Instruction Generalist - Quality Is All You Need),这是一个高质量的中文指令调优数据集。数据来源包括问答社区、维基百科、测验题目和现有的NLP数据集,经过了严酷的过滤和处置惩罚。
我们将使用此中的8000条来自百度贴吧的弱智吧数据进行微调:
ruozhiba-llama3-tt
开始模型训练

设置GPU实例

请访问以下页面,得到详细的交互式引导: LooPIN流动性池
1. LooPIN流动性池:
前往LooPIN的流动性池( LooPIN Network Pool),使用$LOOPIN代币购买GPU时间。以RTX 3080 GPU为例,根据自身需求和预算,在 GPU UserBenchmark 中选择合适的GPU型号。
2. 代币兑换GPU资源:


  • 选择所需的$LOOPIN代币数目。
  • 通过滑块选择GPU数目。
  • 确认兑换量并完成生意业务。
3. 进入Jupyter Notebook:
生意业务乐成后,进入Rented Servers下的Server区域,通过你的长途服务器访问Jupyter Notebook。通常,实例启动需要2-4分钟。
4. 用nvidia-smi验证GPU:
在Jupyter Notebook中,打开新的终端窗口,运行nvidia-smi命令,检查GPU是否已激活。
复制
  1. +-----------------------------------------------------------------------------------------+
  2. | NVIDIA-SMI 550.54.15              Driver Version: 550.54.15      CUDA Version: 12.4     |
  3. |-----------------------------------------+------------------------+----------------------+
  4. | GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
  5. | Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
  6. |                                         |                        |               MIG M. |
  7. |=========================================+========================+======================|
  8. |   0  NVIDIA GeForce RTX 3080        Off |   00000000:01:00.0 Off |                  N/A |
  9. |  0%   39C    P8             21W /  350W |      12MiB /  12288MiB |      0%      Default |
  10. |                                         |                        |                  N/A |
  11. +-----------------------------------------+------------------------+----------------------+
  12. +-----------------------------------------------------------------------------------------+
  13. | Processes:                                                                              |
  14. |  GPU   GI   CI        PID   Type   Process name                              GPU Memory |
  15. |        ID   ID                                                               Usage      |
  16. |=========================================================================================|
  17. +-----------------------------------------------------------------------------------------+
复制代码
安装Unsloth开源训练框架

1. 确认Unsloth安装版本

在Unsloth官方readme中找到对应的版本 ( Unsloth GitHub)
复制
  1. import torch; print('cuda:', torch.version.cuda, '\nPytorch:', torch.__version__)1.
复制代码
返回
复制
  1. cuda: 12.1
  2. Pytorch: 2.2.0+cu1211.2.
复制代码
复制
  1. pip install "unsloth[cu121-ampere-torch220] @ git+https://github.com/unslothai/unsloth.git"1.
复制代码
留意:对于新型RTX 30xx或更高级的GPU,请使用"ampere"路径。
2. Huggingface上下载Llama-7B基础模型

使用Unsloth快速加载预训练模型和分词器。
复制
  1. from unsloth import FastLanguageModel
  2. import torch
  3. max_seq_length = 2048 # 根据需求选择,我们内部支持RoPE缩放!
  4. dtype = None # 无需设置,自动检测。对于Tesla T4, V100使用Float16,对于Ampere+使用Bfloat16。
  5. model, tokenizer = FastLanguageModel.from_pretrained(
  6.     model_name = "unsloth/llama-3-8b-bnb-4bit",
  7.     max_seq_length = max_seq_length,
  8.     dtype = dtype,
  9.     load_in_4bit = True, # 使用4bit量化以减少内存使用。也可以设置为False。
  10. )
复制代码
等候模型下载完成
复制
  1. config.json: 100%
  2.  1.14k/1.14k [00:00<00:00, 72.1kB/s]
  3. ==((====))==  Unsloth: Fast Llama patching release 2024.4
  4.    \\   /|    GPU: NVIDIA GeForce RTX 3080. Max memory: 11.756 GB. Platform = Linux.
  5. O^O/ \_/ \    Pytorch: 2.2.0+cu121. CUDA = 8.6. CUDA Toolkit = 12.1.
  6. \        /    Bfloat16 = TRUE. Xformers = 0.0.24. FA = True.
  7. "-____-"     Free Apache license: http://github.com/unslothai/unsloth
  8. model.safetensors: 100%
  9.  5.70G/5.70G [00:52<00:00, 88.6MB/s]
  10. generation_config.json: 100%
  11.  131/131 [00:00<00:00, 8.23kB/s]
  12. tokenizer_config.json: 100%
  13.  50.6k/50.6k [00:00<00:00, 2.55MB/s]
  14. tokenizer.json: 100%
  15.  9.09M/9.09M [00:00<00:00, 11.6MB/s]
  16. special_tokens_map.json: 100%
  17.  449/449 [00:00<00:00, 28.4kB/s]
复制代码
如需针对其他基础模型进行微调,可在此处找到并替换model_name ( Unsloth Huggingface)。
3. 准备Lora Adapter

我们在微调过程中只需更新1%-10%的模型参数。
复制
  1. model = FastLanguageModel.get_peft_model(
  2.     model,
  3.     r = 16, # 选择任意大于0的数字!推荐值为8, 16, 32, 64, 128。
  4.     target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
  5.                       "gate_proj", "up_proj", "down_proj"],
  6.     lora_alpha = 16,
  7.     lora_dropout = 0, # 支持任意值,但0是最优。
  8.     bias = "none",    # 支持任意值,但"none"是最优。
  9.     # [NEW] "unsloth"使用30%更少的VRAM,可以处理2倍大的批量大小!
  10.     use_gradient_checkpointing = "unsloth", # True或"unsloth"用于非常长的上下文。
  11.     random_state = 3407,
  12.     use_rslora = False,  # 我们支持排名稳定的LoRA。
  13.     loftq_config = None, # 以及LoftQ。
  14. )
复制代码
等候输出
复制
  1. Unsloth 2024.4 patched 32 layers with 32 QKV layers, 32 O layers and 32 MLP layers.1.
复制代码
4. 准备微调数据集

我们将使用一个高质量的中文指令调优数据集子集进行微调。
复制
  1. from datasets import load_dataset
  2. dataset = load_dataset("kigner/ruozhiba-llama3-tt", split = "train")
  3. dataset = dataset.map(formatting_prompts_func, batched = True)
复制代码
等候数据下载完成
复制
  1. Downloading readme: 100%
  2.  28.0/28.0 [00:00<00:00, 4.94kB/s]
  3. Downloading data: 100%
  4.  616k/616k [00:00<00:00, 4.03MB/s]
  5. Generating train split: 100%
  6.  1496/1496 [00:00<00:00, 150511.62 examples/s]
  7. Map: 100%
  8.  1496/1496 [00:00<00:00, 152505.32 examples/s]
复制代码
5. 训练模型

接下来,我们将使用Huggingface的SFTTrainer作为训练框架,详细文档请见 SFT Trainer Documentation.
复制
  1. from trl import SFTTrainer
  2. from transformers import TrainingArguments
  3. trainer = SFTTrainer(
  4.     model = model,
  5.     tokenizer = tokenizer,
  6.     train_dataset = dataset,
  7.     dataset_text_field = "text",
  8.     max_seq_length = max_seq_length,
  9.     dataset_num_proc = 2,
  10.     packing = False, # 可使短序列训练速度提升5倍。
  11.     args = TrainingArguments(
  12.         per_device_train_batch_size = 2,
  13.         gradient_accumulation_steps = 4,
  14.         warmup_steps = 5,
  15.         max_steps = 60,
  16.         learning_rate = 2e-4,
  17.         fp16 = not torch.cuda.is_bf16_supported(),
  18.         bf16 = torch.cuda.is_bf16_supported(),
  19.         logging_steps = 1,
  20.         optim = "adamw_8bit",
  21.         weight_decay = 0.01,
  22.         lr_scheduler_type = "linear",
  23.         seed = 3407,
  24.         output_dir = "outputs",
  25.     ),
  26. )
  27. trainer_stats = trainer.train()
复制代码
在训练过程中,max_steps表现训练步数,可以根据实际情况调整;learning_rate是学习率;output_dir是归并模型的输出目录。设置完成后即可开始训练。
复制
  1. max_steps is given, it will override any value given in num_train_epochs
  2. ==((====))==  Unsloth - 2x faster free finetuning | Num GPUs = 1
  3.    \\   /|    Num examples = 1
  4. ,496 | Num Epochs = 1
  5. O^O/ \_/ \    Batch size per device = 2 | Gradient Accumulation steps = 4
  6. \        /    Total batch size = 8 | Total steps = 60
  7. "-____-"     Number of trainable parameters = 41,943,040
  8. [60/60 01:54, Epoch 0/1]
  9. Step    Training Loss
  10. 1       2.674800
  11. 2       2.681600
  12. 3       2.603500
  13. 4       2.454600
  14. 5       2.463700
  15. 6       2.137400
  16. 7       2.170800
  17. 8       1.690200
  18. 9       1.543300
  19. 10      1.588800
  20. 11      1.434700
  21. 12      1.436800
  22. 13      1.546900
  23. 14      1.473900
  24. 15      1.328600
  25. 16      1.290700
  26. 17      1.428500
  27. 18      1.335700
  28. 19      1.493200
  29. 20      1.276300
  30. 21      1.352100
  31. 22      1.496900
  32. 23      1.501500
  33. 24      1.292600
  34. 25      1.317700
  35. 26      1.240400
  36. 27      1.334700
  37. 28      1.384600
  38. 29      1.261500
  39. 30      1.286000
  40. 31      1.312000
  41. 32      1.301000
  42. 33      1.331100
  43. 34      1.253900
  44. 35      1.374100
  45. 36      1.206200
  46. 37      1.218700
  47. 38      1.167600
  48. 39      1.391100
  49. 40      1.130700
  50. 41      1.298100
  51. 42      1.252400
  52. 43      1.330500
  53. 44      1.340500
  54. 45      1.365700
  55. 46      1.200900
  56. 47      1.163000
  57. 48      1.199100
  58. 49      1.260800
  59. 50      1.290200
  60. 51      1.319400
  61. 52      1.278800
  62. 53      1.326200
  63. 54      1.210400
  64. 55      1.369100
  65. 56      1.186300
  66. 57      1.328200
  67. 58      1.237400
  68. 59      1.245100
  69. 60      1.305800
复制代码
训练步调和训练损失两列数据显示了训练过程中的性能,损失的稳步下降表明模型正在有效学习我们提供的训练素材。整个训练过程不到2分钟即可完成。
6. 模型测试

现在,我们将用中文问题来测试经过微调的Llama3模型的中文处置惩罚能力。
复制
  1. # alpaca_prompt = Copied from above
  2. FastLanguageModel.for_inference(model) # 启用原生2倍速的推理
  3. inputs = tokenizer(
  4. [
  5.     alpaca_prompt.format(
  6.         "只能用中文回答问题", # 指令
  7.         "陨石为什么每次都能精准砸到陨石坑", # 输入
  8.         "", # 输出 - 留空用于生成
  9.     )
  10. ], return_tensors = "pt").to("cuda")
  11. from transformers import TextStreamer
  12. text_streamer = TextStreamer(tokenizer)
  13. _ = model.generate(**inputs, streamer = text_streamer, max_new_tokens = 256)
复制代码
复兴如下:
复制
  1. Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.
  2. ### Instruction:
  3. 只能用中文回答问题
  4. ### Input:
  5. 陨石为什么每次都能精准砸到陨石坑
  6. ### Response:
  7. 陨石坑是由陨石撞击地球形成的,陨石坑的位置和大小取决于陨石的大小、速度和撞击的角度等多种因素。所以,每次陨石撞击地球,都会形成新的陨石坑,而这些陨石坑的位置
  8. 和大小可能会有所不同。所以,陨石每次都能精准砸到陨石坑,是因为陨石坑的位置和大小是随着时间变化的,而陨石的撞击位置和大小是随机的。
复制代码
这表明模型已经具备了中文问答和逻辑推理的能力。
7. 模型生存与量化

Lora 模型

复制
  1. model.save_pretrained("lora_model") # 本地保存1.
复制代码
将训练好的模型先生存为Lora格式,在workspace中找到命名为lora_model的文件夹,里面生存了 README.md、adapter_config.json、adapter_model.safetensors,此中adapter_model.safetensors为Lora文件,可以导入其他Inference推理工具使用。
4bit量化

或者我们可以接纳4bit量化,如许在牺牲极小部分模型精度的同时,可以最大限度地提高推理速率和镌汰显存占用。
复制
  1. model.save_pretrained_merged("model", tokenizer, save_method = "merged_4bit_forced",)1.
复制代码
输出为:
复制
  1. Unsloth: Merging 4bit and LoRA weights to 4bit...
  2. This might take 5 minutes...
  3. /usr/local/lib/python3.10/dist-packages/peft/tuners/lora/bnb.py:325: UserWarning: Merge lora module to 4-bit linear may get different generations due to rounding errors.
  4.   warnings.warn(
  5. Done.
  6. Unsloth: Saving tokenizer... Done.
  7. Unsloth: Saving model... This might take 10 minutes for Llama-7b... Done.
复制代码
此中model文件夹生存了量化后的模型权重。
GGUF/Llama.cpp

也可以生存成gguf格式用于CPU推理。
复制
  1. model.save_pretrained_gguf("model", tokenizer, quantization_method = "q4_k_m")1.
复制代码
等候一段时间后,在/workspace下可以找到文件名为model-unsloth.Q4_K_M.gguf的文件。
总结

本教程详细介绍了怎样使用Unsloth和LooPIN环境对Llama 3进行微调。通过这一过程,我们不仅学会了数据准备和模型训练的焦点步调,还掌握了怎样使用GPU资源进行高效的模型训练。我们会在后续教程中继续探讨LLM的工程实践。
转至:https://blog.51cto.com/u_16765961/10814836

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

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

麻花痒

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