设计网站设计网站,东营房产网信息网,wordpress header js,电子商务网站怎么建设本文将演示如何使用PEFT、QLoRa和Huggingface对新的lama-2进行微调#xff0c;生成自己的代码生成器。所以本文将重点展示如何定制自己的llama2#xff0c;进行快速训练#xff0c;以完成特定任务。 一些知识点
llama2相比于前一代#xff0c;令牌数量增加了40%#xff0…本文将演示如何使用PEFT、QLoRa和Huggingface对新的lama-2进行微调生成自己的代码生成器。所以本文将重点展示如何定制自己的llama2进行快速训练以完成特定任务。 一些知识点
llama2相比于前一代令牌数量增加了40%达到2T上下文长度增加了一倍并应用分组查询注意(GQA)技术来加速在较重的70B模型上的推理。在标准的transformer 体系结构上使用RMSNorm归一化、SwiGLU激活和旋转位置嵌入上下文长度达到了4096个并应用了具有余弦学习率调度、权重衰减0.1和梯度裁剪的Adam优化器。
有监督微调(SFT)阶段的特点是优先考虑质量样本而不是数量因为许多报告表明使用高质量数据可以提高最终模型的性能。
最后通过带有人类反馈的强化学习(RLHF)步骤使模型与用户偏好保持一致。收集了大量示例其中人类在比较中选择他们首选的模型输出。这些数据被用来训练奖励模型。
最主要的一点是LLaMA 2-CHAT已经和OpenAI ChatGPT一样好了所以我们可以使用它作为我们本地的一个替代了
数据集
对于的微调过程我们将使用大约18,000个示例的数据集其中要求模型构建解决给定任务的Python代码。这是原始数据集[2]的提取其中只选择了Python语言示例。每行包含要解决的任务的描述如果适用的话任务的数据输入示例并提供解决任务的生成代码片段[3]。 # Load dataset from the hubdataset load_dataset(dataset_name, splitdataset_split)# Show dataset sizeprint(fdataset size: {len(dataset)})# Show an exampleprint(dataset[randrange(len(dataset))])创建提示
为了执行指令微调我们必须将每个数据示例转换为指令并将其主要部分概述如下: def format_instruction(sample):return f### Instruction:Use the Task below and the Input given to write the Response, which is a programming code that can solve the following Task:### Task:{sample[instruction]}### Input:{sample[input]}### Response:{sample[output]}输出的结果是这样的 ### Instruction:Use the Task below and the Input given to write the Response, which is a programming code that can solve the following Task:### Task:Develop a Python program that prints Hello, World! whenever it is run.### Input:### Response:#Python program to print Hello World!print(Hello, World!)微调模型
为了方便演示我们使用Google Colab环境对于第一次测试运行T4实例就足够了但是当涉及到运行整个数据集训练则需要使用A100。
除此以外还可以登录Huggingface hub 这样可以上传和共享模型当然这个是可选项。 from huggingface_hub import loginfrom dotenv import load_dotenvimport os# Load the enviroment variablesload_dotenv()# Login to the Hugging Face Hublogin(tokenos.getenv(HF_HUB_TOKEN))PEFT、Lora和QLora
训练LLM的通常步骤包括:首先对数十亿或数万亿个令牌进行预训练得到基础模型然后对该模型进行微调使其专门用于下游任务。
参数高效微调(PEFT)允许我们通过微调少量额外参数来大大减少RAM和存储需求因为所有模型参数都保持冻结状态。并且PEFT还增强了模型的可重用性和可移植性它很容易将小的检查点添加到基本模型中通过添加PEFT参数让基础模型在多个场景中重用。最后由于没有调整基本模型还可以保留在预训练阶段获得的所有知识从而避免了灾难性遗忘。
PEFT保持预训练的基本模型不变并在其上添加新的层或参数。这些层被称为“适配器”我们将这些层添加到预训练的基本模型中只训练这些新层的参数。但是这种方法的一个严重问题是这些层会导致推理阶段的延迟增加从而使流程在许多情况下效率低下。
而在LoRa技术(大型语言模型的低秩适应)中不是添加新的层而是以一种避免在推理阶段出现这种可怕的延迟问题的方式向模型各层参数添加值。LoRa训练并存储附加权重的变化同时冻结预训练模型的所有权重。也就是说我们利用预训练模型矩阵的变化训练一个新的权重矩阵并将这个新矩阵分解为2个低秩矩阵如下所示:
LoRA[1]的作者提出权值变化矩阵∆W的变化可以分解为两个低秩矩阵A和b。LoRA不直接训练∆W中的参数而是直接训练A和b中的参数因此可训练参数的数量要少得多。假设A的维数为100 * 1,B的维数为1 * 100则∆W中的参数个数为100 * 100 10000。在A和B中训练的人数只有100 100 200而在∆W中训练的个数是10000
这些低秩矩阵的大小由r参数定义。这个值越小需要训练的参数就越少速度更快。但是参数过少可能会损失信息和性能所以r参数的选择也是需要考虑的问题。
最后QLoRa[6]则是将量化应用于LoRa方法通过优化内存使用的技巧以实现“更轻量”和更便宜的训练。
微调流程
我们的示例中使用QLoRa所以要指定BitsAndBytes配置下载4位量化的预训练模型定义LoraConfig。 # Get the typecompute_dtype getattr(torch, bnb_4bit_compute_dtype)# BitsAndBytesConfig int-4 configbnb_config BitsAndBytesConfig(load_in_4bituse_4bit,bnb_4bit_use_double_quantuse_double_nested_quant,bnb_4bit_quant_typebnb_4bit_quant_type,bnb_4bit_compute_dtypecompute_dtype)# Load model and tokenizermodel AutoModelForCausalLM.from_pretrained(model_id, quantization_configbnb_config, use_cache False, device_mapdevice_map)model.config.pretraining_tp 1# Load the tokenizertokenizer AutoTokenizer.from_pretrained(model_id, trust_remote_codeTrue)tokenizer.pad_token tokenizer.eos_tokentokenizer.padding_side right下面是参数定义, # Activate 4-bit precision base model loadinguse_4bit True# Compute dtype for 4-bit base modelsbnb_4bit_compute_dtype float16# Quantization type (fp4 or nf4)bnb_4bit_quant_type nf4# Activate nested quantization for 4-bit base models (double quantization)use_double_nested_quant False# LoRA attention dimensionlora_r 64# Alpha parameter for LoRA scalinglora_alpha 16# Dropout probability for LoRA layerslora_dropout 0.1接下来的步骤对于所有的Hugging Face用户来说应该都很熟悉了设置训练参数创建Trainer。在执行指令微调时我们调用封装PEFT模型定义和其他步骤的SFTTrainer方法。 # Define the training argumentsargs TrainingArguments(output_diroutput_dir,num_train_epochsnum_train_epochs,per_device_train_batch_sizeper_device_train_batch_size, # 6 if use_flash_attention else 4,gradient_accumulation_stepsgradient_accumulation_steps,gradient_checkpointinggradient_checkpointing,optimoptim,logging_stepslogging_steps,save_strategyepoch,learning_ratelearning_rate,weight_decayweight_decay,fp16fp16,bf16bf16,max_grad_normmax_grad_norm,warmup_ratiowarmup_ratio,group_by_lengthgroup_by_length,lr_scheduler_typelr_scheduler_type,disable_tqdmdisable_tqdm,report_totensorboard,seed42)# Create the trainertrainer SFTTrainer(modelmodel,train_datasetdataset,peft_configpeft_config,max_seq_lengthmax_seq_length,tokenizertokenizer,packingpacking,formatting_funcformat_instruction,argsargs,)# train the modeltrainer.train() # there will not be a progress bar since tqdm is disabled# save model in localtrainer.save_model()这些参数大多数通常用于llm上的其他微调脚本我们就不做过多的说明了 # Number of training epochsnum_train_epochs 1# Enable fp16/bf16 training (set bf16 to True with an A100)fp16 Falsebf16 True# Batch size per GPU for trainingper_device_train_batch_size 4# Number of update steps to accumulate the gradients forgradient_accumulation_steps 1# Enable gradient checkpointinggradient_checkpointing True# Maximum gradient normal (gradient clipping)max_grad_norm 0.3# Initial learning rate (AdamW optimizer)learning_rate 2e-4# Weight decay to apply to all layers except bias/LayerNorm weightsweight_decay 0.001# Optimizer to useoptim paged_adamw_32bit# Learning rate schedulelr_scheduler_type cosine #constant# Ratio of steps for a linear warmup (from 0 to learning rate)warmup_ratio 0.03# Group sequences into batches with same length# Saves memory and speeds up training considerablygroup_by_length False# Save checkpoint every X updates stepssave_steps 0# Log every X updates stepslogging_steps 25# Disable tqdmdisable_tqdm True合并权重
正如上面我们提到的方法LoRa在基本模型上训练了“修改权重”所以最终模型需要将预训练的模型和适配器权重合并到一个模型中。 from peft import AutoPeftModelForCausalLMmodel AutoPeftModelForCausalLM.from_pretrained(args.output_dir,low_cpu_mem_usageTrue,return_dictTrue,torch_dtypetorch.float16,device_mapdevice_map, )# Merge LoRA and base modelmerged_model model.merge_and_unload()# Save the merged modelmerged_model.save_pretrained(merged_model,safe_serializationTrue)tokenizer.save_pretrained(merged_model)# push merged model to the hubmerged_model.push_to_hub(hf_model_repo)tokenizer.push_to_hub(hf_model_repo)推理
最后就是推理的过程了 import torchfrom transformers import AutoModelForCausalLM, AutoTokenizer# Get the tokenizertokenizer AutoTokenizer.from_pretrained(hf_model_repo)# Load the modelmodel AutoModelForCausalLM.from_pretrained(hf_model_repo, load_in_4bitTrue, torch_dtypetorch.float16,device_mapdevice_map)# Create an instructioninstructionOptimize a code snippet written in Python. The code snippet should create a list of numbers from 0 to 10 that are divisible by 2.inputprompt f### Instruction:Use the Task below and the Input given to write the Response, which is a programming code that can solve the Task.### Task:{instruction}### Input:{input}### Response:# Tokenize the inputinput_ids tokenizer(prompt, return_tensorspt, truncationTrue).input_ids.cuda()# Run the model to infere an outputoutputs model.generate(input_idsinput_ids, max_new_tokens100, do_sampleTrue, top_p0.9,temperature0.5)# Print the resultprint(fPrompt:\n{prompt}\n)print(fGenerated instruction:\n{tokenizer.batch_decode(outputs.detach().cpu().numpy(), skip_special_tokensTrue)[0][len(prompt):]})结果如下 Prompt:### Instruction:Use the Task below and the Input given to write the Response, which is a programming code that can solve the Task.### Task:Optimize a code snippet written in Python. The code snippet should create a list of numbers from 0 to 10 that are divisible by 2.### Input:arr []for i in range(10):if i % 2 0:arr.append(i)### Response:Generated instruction:arr [i for i in range(10) if i % 2 0]Ground truth:arr [i for i in range(11) if i % 2 0]看样子还是很不错的
总结
以上就是我们微调llama2的完整过程这里面的一个最重要的步骤其实是提示的生成一个好的提示对于模型的性能也是非常有帮助的。
[1] Llama-2 paper https://arxiv.org/pdf/2307.09288.pdf
[2] python code dataset http://sahil2801/code_instructions_120k
[3] 本文使用的数据集 https://huggingface.co/datasets/iamtarun/python_code_instructions_18k_alpaca
[4] LoRA: Low-Rank Adaptation of Large Language Models. arXiv:2106.09685
[5]. QLoRa: Efficient Finetuning of QuantizedLLMs arXiv:2305.14314
https://avoid.overfit.cn/post/9794c9eef1df4e55adf514b3d727ee3b
作者Eduardo Muñoz