Face技术主管手把手教你微调Llama 3 Hugging 仅用250美元
仅用250美元,Hugging Face技术主管手把手教你微调Llama 3
大言语模型的微调不时是说起来容易做起来难的事儿。近日 Hugging Face 技术主管 Philipp Schmid 宣布了一篇博客,详细解说了如何应用 Hugging Face 上的库和 fsdp 以及 Q-Lora 对大模型启动微调。图片咱们知道,Meta 推出的 Llama 3、Mistral AI 推出的 Mistral 和 Mixtral 模型以及 AI21 试验室推出的 Jamba 等开源大言语模型曾经成为 OpenAI 的竞争对手。
不过,大少数状况下,经常使用者须要依据自己的数据对这些开源模型启动微调,能力充沛监禁模型的后劲。
只管在单个 GPU 上经常使用 Q-Lora 对较小的大言语模型(如 Mistral)启动微调不是难事,但对像 Llama 3 70b 或 Mixtral 这样的大模型的高效微调直到如今仍是一个难题。
因此,Hugging Face 技术主管 Philipp Schmid 引见了如何经常使用 PyTorch FSDP 和 Q-Lora,并在 Hugging Face 的 TRL、Transformers、peft 和>
# Install Pytorch for FSDP and FA/SDPA%pip install "torch==2.2.2" tensorboard# Install Hugging Face libraries%pip install--upgrade "transformers==4.40.0" "datasets==2.18.0" "accelerate==0.29.3" "evaluate==0.4.1" "bitsandbytes==0.43.1" "huggingface_hub==0.22.2" "trl==0.8.6" "peft==0.10.0"
接上去,登录 Hugging Face 失掉 Llama 3 70b 模型。
创立和加载数据集
环境设置成功后,咱们就可以开局创立和预备数据集了。微调用的数据集应该蕴含经常使用者想要处置的义务的示例样本。浏览《如何在 2024 年经常使用 Hugging Face 微调 LLM》可以进一步了解如何创立数据集。
文章地址:
作者经常使用了 HuggingFaceH4/no_robots 数据集,这是一个蕴含 10,000 条指令和样本的高品质数据集,并且经过了高品质的数据标注。这些数据可用于有监视微调(SFT),使言语模型更好地遵照人类指令。no_robots 数据集以 OpenAI 宣布的 InstructGPT 论文中形容的人类指令数据集为原型,并且关键由单句指令组成。
{"messages": [{"role": "system", "content": "You are..."}, {"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]}{"messages": [{"role": "system", "content": "You are..."}, {"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]}{"messages": [{"role": "system", "content": "You are..."}, {"role": "user", "content": "..."}, {"role": "assistant", "content": "..."}]}
no_robots 数据集中的 10,000 个样本,被分为 9,500 个训练样本和 500 个测试样本,其中有些样本不蕴含 system 消息。作者经常使用>
from, force_ascii=False)dataset["test"].to_json("test_dataset.json", orient="records", force_ascii=False)
经常使用 PyTorch FSDP、Q-Lora 和 SDPA 来微调 LLM
接上去经常使用 PyTorch FSDP、Q-Lora 和 SDPA 对大言语模型启动微调。作者是在散布式设施中运转模型,因此须要经常使用 torchrun 和 python 脚本启动训练。
作者编写了 run_fsdp_qlora.py 脚本,其作用是从磁盘加载数据集、初始化模型和分词器并开局模型训练。脚本经常使用 trl 库中的 SFTTrainer 来对模型启动微调。
SFTTrainer 能够让对开源大言语模型的有监视微调愈加容易上手,详细来说有以下几点:
格局化的数据集,包括格局化的多轮会话和指令(已经常使用)只对完整的内容启动训练,疏忽只要 prompts 的状况(未经常使用)打包数据集,提高训练效率(已经常使用)支持参数高效微调技术,包括 Q-LoRA(已经常使用)为会话级义务微调初始化模型和分词器(未经常使用,见下文)
留意:作者经常使用的是相似于 Anthropic/Vicuna 的聊天模板,设置了「用户」和「助手」角色。这样做是由于基础 Llama 3 中的不凡分词器(<|begin_of_text|> 及 <|reserved_special_token_XX|>)没有经过训练。
这象征着假设要在模板中经常使用这些分词器,还须要对它们启动训练,并降级嵌入层和 lm_head,对内存会发生额外的需求。假设经常使用者有更多的算力,可以修正 run_fsdp_qlora.py 脚本中的 LLAMA_3_CHAT_TEMPLATE 环境变量。
在性能参数方面,作者经常使用了新的 TrlParser 变量,它准许咱们在 yaml 文件中提供超参数,或许经过明白地将参数传递给 CLI 来笼罩性能文件中的参数,例如 —num_epochs 10。以下是在 4x A10G GPU 或 4x24GB GPU 上微调 Llama 3 70B 的性能文件。
%%writefile llama_3_70b_fsdp_qlora.yaml# script parametersmodel_id: "meta-llama/Meta-Llama-3-70b" # Hugging Face model iddataset_path: "."# path to>
留意:训练完结时,GPU 内存经常使用量会略有参与(约 10%),这是由于模型保留所带来的开支。所以经常使用时,请确保 GPU 上有足够的内存来保留模型。
在启动模型训练阶段,作者经常使用 torchrun 来愈加灵敏地运用样本,并且易于被调整,就像 Amazon SageMaker 及 Google Cloud Vertex AI 一样。
关于 torchrun 和 FSDP,作者须要对环境变量 ACCELERATE_USE_FSDP 和 FSDP_CPU_RAM_EFFICIENT_LOADING 启动设置,来通知 transformers/accelerate 经常使用 FSDP 并以节俭内存的方式加载模型。
留意:假构想不经常使用 CPU offloading 性能,须要更改 fsdp 的设置。这种操作只适用于内存大于 40GB 的 GPU。
本文经常使用以下命令启动训练:
!ACCELERATE_USE_FSDP=1 FSDP_CPU_RAM_EFFICIENT_LOADING=1 torchrun --nproc_per_node=4 ./scripts/run_fsdp_qlora.py --config llama_3_70b_fsdp_qlora.yaml
预期内存经常使用状况:
在 g5.12xlarge 主机上,基于蕴含 1 万个样本的数据集,作者经常使用 Flash Attention 对 Llama 3 70B 启动 3 个 epoch 的训练,总共须要 45 小时。每小时老本为 5.67 美元,总老本为 255.15 美元。这听起来很贵,但可以让你在较小的 GPU 资源上对 Llama 3 70B 启动微调。
假设咱们将训练扩展到 4x H100 GPU,训练期间将缩短至大概 125 小时。假设假定 1 台 H100 的老本为 5-10 美元 / 小时,那么总老本将在 25-50 美元之间。
咱们须要在易用性和性能之间做出掂量。假设能取得更多更好的计算资源,就能缩小训练期间和老本,但即使只要大批资源,也能对 Llama 3 70B 启动微调。关于 4x A10G GPU 而言,须要将模型加载到 CPU 上,这就降落了总体 flops,因此老本和性能会有所不同。
留意:在作者启动的评价和测试环节中,他留意到大概 40 个最大步长(将 80 个样本重叠为长度为三千的序列)就足以取得初步结果。40 个步长的训练期间约为 1 小时,老本约合 5 美元。
可选步骤:将 LoRA 的适配器融入原始模型
经常使用 QLoRA 时,作者只训练适配器而不对整个模型做出修正。这象征着在训练环节中保留模型时,只保留适配器权重,而不保留完整模型。
假设经常使用者想保留完整的模型,使其更容易与文本生成推理器一同经常使用,则可以经常使用 merge_and_unload 方法将适配器权重兼并到模型权重中,而后经常使用 save_pretrained 方法保留模型。这将保留一个自动模型,可用于推理。
留意:CPU 内存须要大于 192GB。
#### COMMENT IN TO MERGE PEFT AND BASE MODEL ##### from peft import AutoPeftModelForCausalLM# # Load PEFT model on CPU# model = AutoPeftModelForCausalLM.from_pretrained(#args.output_dir,#torch_dtype=torch.float16,#low_cpu_mem_usage=True,# )# # Merge LoRA and base model and save# merged_model = model.merge_and_unload()# merged_model.save_pretrained(args.output_dir,safe_serialization=True, max_shard_size="2GB")
模型测试和推理
训练成功后,咱们要对模型启动评价和测试。作者从原始数据集中加载不同的样本,并手动评价模型。评价生成式人工自动模型并非易事,由于一个输入或许有多个正确的输入。浏览《评价 LLMs 和 RAG,一个经常使用 Langchain 和 Hugging Face 的适用案例》可以了解到关于评价生成模型的关系内容。
文章地址:
import torchfrom peft import AutoPeftModelForCausalLMfrom transformers import AutoTokenizerpeft_model_id = "./llama-3-70b-hf-no-robot"# Load Model with PEFT adaptermodel = AutoPeftModelForCausalLM.from_pretrained(peft_model_id,torch_dtype=torch.float16,quantization_config= {"load_in_4bit": True},device_map="auto")tokenizer = AutoTokenizer.from_pretrained(peft_model_id)
接上去加载测试数据集,尝试生成指令。
from, split="train")rand_idx = randint(0, len(eval_dataset))messages = eval_dataset[rand_idx]["messages"][:2]# Test on sampleinput_ids = tokenizer.apply_chat_template(messages,add_generation_prompt=True,return_tensors="pt").to(model.device)outputs = model.generate(input_ids,max_new_tokens=512,eos_token_id= tokenizer.eos_token_id,do_sample=True,temperature=0.6,top_p=0.9,)response = outputs[0][input_ids.shape[-1]:]print(f"**Query:**\n{eval_dataset[rand_idx]['messages'][1]['content']}\n")print(f"**Original Answer:**\n{eval_dataset[rand_idx]['messages'][2]['content']}\n")print(f"**Generated Answer:**\n{tokenizer.decode(response,skip_special_tokens=True)}")# **Query:**# How long was the Revolutionary War?# **Original Answer:**# The American Revolutionary War lasted just over seven years. The war started on April 19, 1775, and ended on September 3, 1783.# **Generated Answer:**# The Revolutionary War, also known as the American Revolution, was an 18th-century war fought between the Kingdom of Great Britain and the Thirteen Colonies. The war lasted from 1775 to 1783.
至此,关键流程就引见完了,心动不如执行,连忙从第一步开局操作吧。