Alpaca-lora代码实战

1,049 阅读5分钟

导语

之前的几篇博客介绍了Meta开源的大模型LLaMA(juejin.cn/post/722436… )以及斯坦福研究团队在LLaMA-7B基础上训练得到的堪比GPT-3.5的模型Alpaca(juejin.cn/post/722440… )。尽管Alpaca使用的是最小size的LLaMA模型,但7B的参数量使得训练时仍需要使用8张80G A100的算力来完成。最近,一些尝试使用LoRA技术来完成LLaMA模型的Alpaca调优,一起来看看吧。

1 简介

LoRA方法,通过假设在模型适应过程中权重变化具有较低的内在秩,从而优化在矩阵乘法的计算量来大大提升训练效率,是目前广受欢迎的一种技术。Alpaca-LoRA则是将该方法应用于LLaMA模型训练的代码库。该Repo包含用于使用LoRA复现Stanford Alpaca结果的代码。作者提供了一个与text-davincii-003质量相似的指令调优模型,并且代码很容易扩展到13b、30b和65b模型。

整个训练在单个RTX 4090上只需要运行几个小时。在没有超参数调优的情况下,LoRA模型产生的输出可与Stanford Alpaca模型相媲美。

2 环境建立

整个环境设置非常简单,只需要新建一个conda环境,将该repo克隆到本地后使用pip install安装包即可。 其中,requirements.txt文档中的内容为:

accelerate
appdirs
loralib
bitsandbytes
black
black[jupyter]
datasets
fire
git+https://github.com/huggingface/peft.git
transformers>=4.28.0
sentencepiece
gradio

理想情况下,只需要

pip install -r requirements.txt

即可完成安装,这里记录一下我踩坑的一个地方:

  • peft安装失败:由于网络原因,在进行安装时总会报告peft克隆超时,为此我们可以通过先试用网页将zip格式的peft的github项目对应的zip包下载到本地,然后再进行安装,这时,需要我们修改requirements.txt的内容,将peft那一行修改为本地路径:
……
fire
/path/to/local/package/peft 
transformers>=4.28.0
……

3 训练

训练主要使用finetune.py,该文件包含对LLaMA模型的PEFT的直接应用程序,以及与prompt构造和tokenization相关的一些代码。

一个运行示例如下所示:

python finetune.py \
    --base_model 'decapoda-research/llama-7b-hf' \
    --data_path 'yahma/alpaca-cleaned' \
    --output_dir './lora-alpaca' \
    --batch_size 128 \
    --micro_batch_size 4 \
    --num_epochs 3 \
    --learning_rate 1e-4 \
    --cutoff_len 512 \
    --val_set_size 2000 \
    --lora_r 8 \
    --lora_alpha 16 \
    --lora_dropout 0.05 \
    --lora_target_modules '[q_proj,v_proj]' \
    --train_on_inputs \
    --group_by_length

这里简要介绍一下几个参数:

  • base_model:即基础的大模型,这里使用了Huggingface上的7B的半精度模型;
  • data_path: 训练大模型所需的数据,每一条样例包含了instruction、input和output三个字段;
  • output_dir:输出checkpoint的存储目录;
  • batch_size:批次大小;
  • micro_batch_size:由于采用了Gradient accumulation技术,这里展示的是实际上每个小step的批次大小,但是每个小的step不进行梯度回传,只有达到batch size时才回传一次;
  • num_epochs:训练的epoch数;
  • learning_rate:学习率;
  • cutoff_len:截断长度;
  • val_set_size:验证集大小,由于alpaca只给出了一个数据文件,所以这里从其中分割出2000条作为验证数据集;
  • lora_r、lora_alpha、lora_dropout、lora_target_module:都是跟LoRA相关的参数,其中r代表了设置的秩的大小,lora_target_module则决定了要对哪些模块进行LoRA调优,一共有四个(k,q,v,o)

4 推理

推理主要使用generate.py,这个文件从Huggingface模型库中读取基础模型和从tloen/alpaca-lora-7b中读取的LoRA权重,然后在指定输入上运行一个Gradio接口以进行推理。用户应该将其视为使用该模型的示例代码,并根据需要进行修改。

一个运行示例如下所示:

python generate.py \
    --load_8bit \
    --base_model 'decapoda-research/llama-7b-hf' \
    --lora_weights 'tloen/alpaca-lora-7b'

启动之后,我们可以看到

(alpaca) jiexing@yuji:~/project/llm/llama/alpaca-lora$ CUDA_VISIBLE_DEVICES=5 python3 generate.py --base_model decapoda-research/llama-7b-hf

===================================BUG REPORT===================================
Welcome to bitsandbytes. For bug reports, please run

python -m bitsandbytes

 and submit this information together with your error trace to: https://github.com/TimDettmers/bitsandbytes/issues
================================================================================
bin /home/jiexing/anaconda3/envs/alpaca/lib/python3.9/site-packages/bitsandbytes/libbitsandbytes_cuda113.so
/home/jiexing/anaconda3/envs/alpaca/lib/python3.9/site-packages/bitsandbytes/cuda_setup/main.py:145: UserWarning: Found duplicate ['libcudart.so', 'libcudart.so.11.0', 'libcudart.so.12.0'] files: {PosixPath('/home/jiexing/anaconda3/envs/alpaca/lib/libcudart.so'), PosixPath('/home/jiexing/anaconda3/envs/alpaca/lib/libcudart.so.11.0')}.. We'll flip a coin and try one of these, in order to fail forward.
Either way, this might cause trouble in the future:
If you get `CUDA error: invalid device function` errors, the above might be the cause and the solution is to make sure only one ['libcudart.so', 'libcudart.so.11.0', 'libcudart.so.12.0'] in the paths that we search based on your env.
  warn(msg)
CUDA SETUP: CUDA runtime path found: /home/jiexing/anaconda3/envs/alpaca/lib/libcudart.so
CUDA SETUP: Highest compute capability among GPUs detected: 8.9
CUDA SETUP: Detected CUDA version 113
CUDA SETUP: Loading binary /home/jiexing/anaconda3/envs/alpaca/lib/python3.9/site-packages/bitsandbytes/libbitsandbytes_cuda113.so...
The tokenizer class you load from this checkpoint is not the same type as the class this function is called from. It may result in unexpected tokenization. 
The tokenizer class you load from this checkpoint is 'LLaMATokenizer'. 
The class this function is called from is 'LlamaTokenizer'.
Loading checkpoint shards: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 33/33 [00:25<00:00,  1.27it/s]
/home/jiexing/anaconda3/envs/alpaca/lib/python3.9/site-packages/gradio/inputs.py:27: UserWarning: Usage of gradio.inputs is deprecated, and will not be supported in the future, please import your component from gradio.components
  warnings.warn(
/home/jiexing/anaconda3/envs/alpaca/lib/python3.9/site-packages/gradio/deprecation.py:40: UserWarning: `optional` parameter is deprecated, and it has no effect
  warnings.warn(value)
/home/jiexing/anaconda3/envs/alpaca/lib/python3.9/site-packages/gradio/deprecation.py:40: UserWarning: `numeric` parameter is deprecated, and it has no effect
  warnings.warn(value)
Running on local URL:  http://0.0.0.0:7861

To create a public link, set `share=True` in `launch()`.

这里,我们根据提示可以打开 http://0.0.0.0:7861 会看到如下的界面,其中我们可以输入指令instruction和内容input,点击submit稍等几秒钟就可以得到模型的输出。

image.png

5 效果展示

这个代码库展示了一些样例,不妨来看下:

image.png

6 总结

本文介绍了使用LoRA技术实现一个Alpaca模型的调优代码库,通过引入LoRA,只用一张4090显卡就可以得到与原始Alpaca(8张80G A100)相当的结果,感兴趣的同学快去试一试吧。

7 参考

  1. 🦙🌲🤏 Alpaca-LoRA, github.com/tloen/alpac…