# LLAMA
## 论文
`LLaMA: Open and Efficient Foundation Language Models`
- [https://arxiv.org/abs/2302.13971](https://arxiv.org/abs/2302.13971)
## 模型结构
LLaMA,这是一个基础语言模型的集合,参数范围从7B到65B。在数万亿的tokens上训练出的模型,并表明可以专门使用公开可用的数据集来训练最先进的模型,而不依赖于专有的和不可访问的数据集。特别是,llama 13B在大多数基准测试中优于GPT-3 (175B), LLaMA 65B与最好的模型Chinchilla-70B和PaLM-540B具有竞争力。LLAMA网络基于 Transformer 架构。提出了各种改进,并用于不同的模型,例如 PaLM。
以下是llama-13B的主要网络参数配置:
```
{
"architectures": [
"LlamaForCausalLM"
],
"bos_token_id": 1,
"eos_token_id": 2,
"hidden_size": 5120,
"initializer_range": 0.02,
"intermediate_size": 13824,
"max_position_embeddings": 2048,
"model_type": "llama",
"num_attention_heads": 40,
"num_hidden_layers": 40,
"pad_token_id": 0,
"paddlenlp_version": null,
"rms_norm_eps": 1e-06,
"use_recompute": false,
"vocab_size": 32000
}
```
## 算法原理
以下是与原始 Transformer 架构的主要区别:
**预归一化**。为了提高训练稳定性,对每个transformer 子层的输入进行归一化,而不是对输出进行归一化。使用 RMSNorm 归一化函数。
**SwiGLU 激活函数 [PaLM]**。使用 SwiGLU 激活函数替换 ReLU 非线性以提高性能。使用 2 /3 4d 的维度而不是 PaLM 中的 4d。
**旋转嵌入**。移除了绝对位置嵌入,而是添加了旋转位置嵌入 (RoPE),在网络的每一层。
## 数据集
### 增量预训练
数据详细制作流程可参考[此处](https://github.com/PaddlePaddle/PaddleNLP/blob/develop/model_zoo/ernie-1.0/preprocess/README.md),例:OpenWebText2预训练数据制作参考[此处](https://github.com/PaddlePaddle/PaddleNLP/blob/develop/model_zoo/ernie-1.0/preprocess/docs/OpenWebText2.md)
为了方便用户运行测试本模型,本项目提供了处理好的100k条doc的训练样本:
cd ./llm/llama/
mkkdir data && cd data
wget https://bj.bcebos.com/paddlenlp/models/transformers/llama/data/llama_openwebtext_100k_ids.npy
wget https://bj.bcebos.com/paddlenlp/models/transformers/llama/data/llama_openwebtext_100k_idx.npz
cd .. && tree data
data
├── llama_openwebtext_100k_ids.npy
└── llama_openwebtext_100k_idx.npz
### SFT
```
cd ./llm/
wget https://bj.bcebos.com/paddlenlp/datasets/examples/AdvertiseGen.tar.gz
tar -zxvf AdvertiseGen.tar.gz
```
## 环境配置
### Docker
推荐使用docker方式运行,提供拉取的docker镜像,关于本项目所需新版本 DTK 等均可从[光合](https://developer.hpccube.com/tool/)开发者社区下载安装,docker中默认使用dtk-23.04.1:
```
docker pull registry.baidubce.com/device/paddle-dcu:dtk23.04.1-centos79-x86_64-gcc73
docker run -it --network=host --name=paddle_llama --privileged --device=/dev/kfd --device=/dev/dri --ipc=host --shm-size=16G --group-add video --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -u root --ulimit stack=-1:-1 --ulimit memlock=-1:-1 -v `pwd`:/home registry.baidubce.com/device/paddle-dcu:dtk23.04.1-centos79-x86_64-gcc73 /bin/bash
# 替换DTK-23.10
pip install paddlenlp==2.6.1 -i http://mirrors.aliyun.com/pypi/simple/
wget http://10.6.10.68:8000/customized/paddle/llama/paddlepaddle_dtk2310-2.5.1-cp39-cp39-linux_x86_64.whl
pip3 install paddlepaddle_dtk2310-2.5.1-cp39-cp39-linux_x86_64.whl
pip3 install tool_helpers visualdl==2.5.3 -i http://mirrors.aliyun.com/pypi/simple/
```
## 训练
### 增量预训练
权重链接
13B:[https://bj.bcebos.com/paddlenlp/models/community/facebook/llama-13b](https://bj.bcebos.com/paddlenlp/models/community/facebook/llama-13b)
7B:[https://bj.bcebos.com/paddlenlp/models/community/facebook/llama-7b](https://bj.bcebos.com/paddlenlp/models/community/facebook/llama-7b)
该训练脚本需要1节点,每节点8张DCU-Z100L-32G。
并行配置采用TP 8,PP 1,使用fp16精度预训练,配置如下:
```
--model_type "llama" \
--model_name_or_path "facebook/llama-13b" \
--tokenizer_name_or_path "facebook/llama-13b" \
--input_dir "./data" \
--output_dir "output/$task_name" \
--split 949,50,1 \
--max_seq_length 2048 \
--per_device_train_batch_size 1 \
--gradient_accumulation_steps 2 \
--per_device_eval_batch_size 2 \
--use_flash_attention 0 \
--use_fused_rms_norm 0 \
--fp16 \
--fp16_opt_level "O2" \
--scale_loss 512 \
--tensor_parallel_degree 8 \
--learning_rate 0.00001 \
--min_learning_rate 0.000001 \
--max_steps 10000 \
--save_steps 5000 \
--weight_decay 0.01 \
--warmup_ratio 0.01 \
--max_grad_norm 1.0 \
--logging_steps 10 \
--dataloader_num_workers 1 \
--eval_steps 1000 \
--report_to "visualdl" \
--sharding "stage1" \
--disable_tqdm true \
--continue_training 1 \
--recompute 1 \
--recompute_granularity full \
--do_train \
--do_eval \
--device "gpu" \
--distributed_dataloader 1
```
增量预训练命令:
```
cd ./llm/llama/
bash run_trainer_tp8.sh
```
注意:
1. `continue_training` 表示从现有的预训练模型加载训练。7b,13b模型初始loss大概为1.9x, 随机初始化模型loss从11.x左右下降。
2. 多机训练时,若各机器使用的训练数据文件位置相同(例如挂载共享硬盘情况),请指定`--share_folder true`使全局0号卡制作缓存数据。否则默认各台机器的0号卡独立制作缓存数据,
3. 若数据集文件夹中存在默认缓存文件夹`index-cache/`,则额外指定的`--data_cache`不生效,训练时优先加载默认缓存文件夹中的内容。
### SFT
权重链接
13B:[https://bj.bcebos.com/paddlenlp/models/community/facebook/llama-13b](https://bj.bcebos.com/paddlenlp/models/community/facebook/llama-13b)
7B:[https://bj.bcebos.com/paddlenlp/models/community/facebook/llama-7b](https://bj.bcebos.com/paddlenlp/models/community/facebook/llama-7b)
该训练脚本需要1节点,每节点8张DCU-Z100L-32G。
并行配置采用TP 8,PP 1,使用fp16精度微调,配置如下:
```
{
"model_name_or_path": "facebook/llama-13b",
"dataset_name_or_path": "./data",
"output_dir": "./checkpoints/llama_sft_ckpts",
"per_device_train_batch_size": 1,
"gradient_accumulation_steps": 4,
"per_device_eval_batch_size": 4,
"eval_accumulation_steps":16,
"num_train_epochs": 3,
"learning_rate": 3e-05,
"warmup_steps": 30,
"logging_steps": 1,
"evaluation_strategy": "epoch",
"save_strategy": "epoch",
"src_length": 256,
"max_length": 512,
"fp16": true,
"fp16_opt_level": "O2",
"do_train": true,
"do_eval": true,
"disable_tqdm": true,
"load_best_model_at_end": true,
"eval_with_do_generation": false,
"metric_for_best_model": "accuracy",
"recompute": true,
"save_total_limit": 1,
"tensor_parallel_degree": 8
}
```
SFT命令:
```
cd ./llm
python3 -u -m paddle.distributed.launch --gpus "0,1,2,3,4,5,6,7" finetune_generation.py ./llama/sft_tp_argument.json
```
## result
### 增量预训练精度
训练数据:[https://bj.bcebos.com/paddlenlp/models/transformers/llama/data](https://bj.bcebos.com/paddlenlp/models/transformers/llama/data)
使用的GPGPU:8张DCU-Z100L-32G。
模型精度(max_sequence_length: 2048):
| 卡数 | 分布式工具 | 收敛性 |
| :------: | :------: |:------: |
| 8 | Paddle | |
### SFT精度
训练数据:[https://bj.bcebos.com/paddlenlp/datasets/examples/AdvertiseGen.tar.gz](https://bj.bcebos.com/paddlenlp/datasets/examples/AdvertiseGen.tar.gz)
使用的GPGPU:8张DCU-Z100L-32G。
模型精度(max_sequence_length: 512):
| 卡数 | 分布式工具 | 收敛性 |
| :--: | :--------: | :----------------------------------------------------------: |
| 8 | Paddle | train_loss 0.7左右波动 / 2 epoches,eval_loss: 1.03, eval_accuracy: 0.739, eval_ppl: 2.82 |
## benchmark
### 训练benchmark
使用的GPGPU:8张DCU-Z100L-32G。
数据集使用[tatsu-lab/alpaca · Datasets at Hugging Face](https://huggingface.co/datasets/tatsu-lab/alpaca),将数据集放置在./examples/benchmark/peft/paddle下:
```
$tree tatsu-lab
tatsu-lab/
└── alpaca
└── data
└── train-00000-of-00001-a09b74b3ef9c3b56.parquet
```
训练benchmark测试命令:
```
cd ./examples/benchmark/peft/paddle
RCCL_NCHANNELS=8 HSA_FORCE_FINE_GRAIN_PCIE=1 python3 -m paddle.distributed.launch --gpus "0,1,2,3,4,5,6,7" benchmark.py --model_name_or_path facebook/llama-13b --english --train_data_size 1000 --intokens --intokens_length 1024 --num_train_epochs 1 --per_device_train_batch_size 2 --gradient_accumulation_steps 2 --evaluation_strategy no --save_strategy no --fp16 --fp16_opt_level O2 --recompute --tensor_parallel_degree 8 --logging_steps 50 --output_dir outputs
```
### 推理benchmark 1
使用的GPGPU:1张DCU-Z100L-32G。
```
cd ./examples/benchmark/peft/paddle
python3 inference_benchmark.py --model_name_or_path facebook/llama-13b --dtype float16 --do_forward --do_generate
```
### 推理benchmark 2(换用[PaddleNLP-develop](https://github.com/PaddlePaddle/PaddleNLP/tree/28158b9735837495e6c73f848925e1d72b821863))
使用的GPGPU:1张DCU-Z100L-32G。
```
pip3 uninstall paddlenlp
cd ./llm
PYTHONPATH=../:$PYTHONPATH \
python3 predictor.py --model_name_or_path facebook/llama-13b --dtype float16 --src_length 300 --max_length 100 --output_file "infer.json" --batch_size 1 --benchmark
```
### LAMBADA推理评估
使用的GPGPU:1张DCU-Z100L-32G。
```
cd ./examples/benchmark/lambada
wget https://paddlenlp.bj.bcebos.com/data/benchmark/lambada_test.jsonl
```
评估LAMBADA数据集,运行以下脚本:
```
python3 eval.py \
--model_name_or_path facebook/llama-13b \
--batch_size 4 \
--eval_path lambada_test.jsonl \
--tensor_parallel_degree 1 \
--cloze_eval
```
## 应用场景
### 算法类别
`自然语言处理`
### 热点应用行业
`医疗,教育,科研,金融`
## 源码仓库及问题反馈
- [https://developer.hpccube.com/codes/modelzoo/llama_paddle](https://developer.hpccube.com/codes/modelzoo/llama_paddle)
## 参考
* [https://github.com/PaddlePaddle/PaddleNLP](https://github.com/PaddlePaddle/PaddleNLP)