Tensorboard指定输出位置
report_to "tensorboard" \
logging_steps 500 \
logging_dir ${logging_dir }
#参数解释:
report_to="tensorboard": 将所有训练和验证的数据报告给 tensorboard
logging_steps:每隔多少步打印一次train loss,结果会打印到日志中,也会保存在tensorboard中
logging_dir: 指定快照输出位置
基于开发机镜像执行llama
docker run -it -u root --name Chinesellama2 -v ~/llama:/root/llama --gpus all fb79aa125061 /bin/bash
pip uninstall bitsandbytes
pip install scikit_learn-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
# 当时的尝试步骤:
# 1安装scikit-learn
# 2 卸载掉bitsandbytes
# 3测试
>>> import torch
>>> print(torch.cuda.is_available())
False
# 加入GPU参数--gpus all 创建docker容器
# 重复123,欧克
镜像上传到harbor,为后续在k8s上执行打基础
docker images
docker tag image_name:v_version harbor_address:port/project_name/new_image_name:new_v_version
docker login harbor_address:port
docker push harbor_address:port/project_name/new_image_name:new_v_version
因为上传到harbor很慢,所以用tmux终端多路复用程序,快速切换界面,以下为主要用到的操作
连接到会话
tmux attach -t 19
tmux attach -t <session_name>
列出所有会话
tmux list-sessions
ctrl+b w列出所有列表
ctrl+b kill-session 将当前会话结束(kill)
ctrl+b d退出当前会话(detach)
llama2的ptuning实现实战
# 参考 github.com/liguodongiot/llm-action/blob/main/train/peft/clm/peft_p_tuning_clm.ipynb 实现ptuning
# 基于github.com/ymcui/Chinese-LLaMA-Alpaca-2/blob/main/scripts/training/run_clm_sft_with_peft.py修改代码
# 首先去掉Lora部分代码,添加实现ptuning的peft相关库
from peft import (
get_peft_config,
TaskType,
get_peft_model,
PeftModel,
get_peft_model_state_dict,
set_peft_model_state_dict,
PromptEncoderConfig,
)
# 然后创建peft配置,即创建ptuning微调方法的相关配置
peft_config = PromptEncoderConfig(task_type=TaskType.CAUSAL_LM, num_virtual_tokens=20, encoder_hidden_size=128)
训练脚本run_sft_test_ptuning.sh
lr=1e-4
pretrained_model=/root/llama/correspond_output_dir
chinese_tokenizer_path=/root/llama/correspond_output_dir
dataset_dir=data_pt
per_device_train_batch_size=1
per_device_eval_batch_size=1
gradient_accumulation_steps=8
max_seq_length=512
output_dir=test
validation_file=data_pt/alpaca_data.json
training_steps=1000
deepspeed_config_file=scripts/training/ds_zero2_no_offload.json
torchrun --nnodes 1 --nproc_per_node 7 scripts/training/run_clm_sft_with_ptuning.py \
--deepspeed ${deepspeed_config_file} \
--model_name_or_path ${pretrained_model} \
--tokenizer_name_or_path ${chinese_tokenizer_path} \
--dataset_dir ${dataset_dir} \
--per_device_train_batch_size ${per_device_train_batch_size} \
--per_device_eval_batch_size ${per_device_eval_batch_size} \
--do_train \
--do_eval \
--eval_steps 1000 \
--seed $RANDOM \
--fp16 \
--num_train_epochs 1 \
--lr_scheduler_type cosine \
--learning_rate ${lr} \
--warmup_ratio 0.03 \
--weight_decay 0 \
--logging_strategy steps \
--logging_steps 10 \
--save_strategy steps \
--save_total_limit 3 \
--evaluation_strategy steps \
--eval_steps 1000 \
--save_steps 1000 \
--gradient_accumulation_steps ${gradient_accumulation_steps} \
--preprocessing_num_workers 8 \
--max_steps ${training_steps} \
--max_seq_length ${max_seq_length} \
--output_dir ${output_dir} \
--overwrite_output_dir \
--ddp_timeout 30000 \
--logging_first_step True \
--torch_dtype float16 \
--validation_file ${validation_file}
llama2的ptuning v2实现实战
# 参考 github.com/liguodongiot/llm-action/blob/main/train/peft/clm/peft_p_tuning_clm.ipynb 实现ptuning
# 基于github.com/ymcui/Chinese-LLaMA-Alpaca-2/blob/main/scripts/training/run_clm_sft_with_peft.py修改代码
# 首先去掉Lora部分代码,添加实现ptuning v2的peft相关库
from peft import (
get_peft_config,
TaskType,
get_peft_model,
PeftModel,
get_peft_model_state_dict,
set_peft_model_state_dict,
PrefixTuningConfig,
)
# 然后创建peft配置,即创建ptuning微调方法的相关配置
peft_config = PrefixTuningConfig(task_type=TaskType.CAUSAL_LM, num_virtual_tokens=300)
trainable params: 78643200 || all params: 7007899648 || trainable%: 1.122207850428397
精华部分(踩坑部分)
if training_args.gradient_checkpointing and \
(not model.modules_to_save or 'embed_tokens' not in model.modules_to_save):
# enable requires_grad to avoid exception during backward pass when using gradient_checkpoint without tuning embed.
if hasattr(model.base_model, "enable_input_require_grads"):
model.base_model.enable_input_require_grads()
elif hasattr(model.base_model, "get_input_embeddings"):
def make_inputs_require_grad(_module, _input, _output):
_output.requires_grad_(True)
model.base_model.get_input_embeddings().register_forward_hook(make_inputs_require_grad)
这段代码主要是在处理模型训练中的梯度检查点问题。梯度检查点是一种内存优化技术,可以在训练深度神经网络时减少GPU内存的使用,但可能会增加一些计算开销。
-
if training_args.gradient_checkpointing and (not model.modules_to_save or 'embed_tokens' not in model.modules_to_save):
这行代码首先检查是否开启了梯度检查点(gradient_checkpointing
),并且模型没有需要保存的模块(modules_to_save
)或者'embed_tokens'
不在需要保存的模块中。如果这两个条件都满足,那么就会执行下面的代码。 -
if hasattr(model.base_model, "enable_input_require_grads"):
这行代码检查基础模型(base_model
)是否有一个名为enable_input_require_grads
的方法。如果有,那么就调用这个方法,使得输入向量可以计算梯度。 -
elif hasattr(model.base_model, "get_input_embeddings"):
这行代码在上一个条件不满足的情况下执行。它检查基础模型是否有一个名为get_input_embeddings
的方法。如果有,那么就注册一个前向钩子(forward_hook
)到输入嵌入向量上。这个钩子会在每次前向传播时被调用,并使得输出向量可以计算梯度。
总的来说,这段代码的目的是在使用梯度检查点时确保输入向量可以计算梯度,以避免在反向传播过程中出现异常。这是因为当使用梯度检查点时,PyTorch会在前向传播过程中释放一些中间结果以节省内存,然后在反向传播过程中重新计算这些结果。如果输入向量不能计算梯度,那么在反向传播过程中就可能出现问题。
llama2的全量微调实现实战
参考github.com/FlagAlpha/Llama2-Chinese/blob/main/train/sft/finetune.sh
github.com/FlagAlpha/Llama2-Chinese/blob/main/train/sft/finetune_clm.py
output_model=./finetune_output
# 需要修改到自己的输入目录
if [ ! -d ${output_model} ];then
mkdir ${output_model}
fi
cp ./finetune.sh ${output_model}
CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6 deepspeed --num_gpus 7 finetune_clm.py \
--model_name_or_path /root/llama/correspond_output_dir \
--per_device_train_batch_size 1 \
--per_device_eval_batch_size 1 \
--train_files ./finetune_data/train_sft.csv \
--validation_files ./finetune_data/dev_sft.csv \
./finetune_data/dev_sft_sharegpt.csv \
--do_train \
--do_eval \
--use_fast_tokenizer false \
--output_dir ${output_model} \
--evaluation_strategy steps \
--max_eval_samples 800 \
--learning_rate 1e-4 \
--gradient_accumulation_steps 8 \
--num_train_epochs 10 \
--warmup_steps 40 \
--logging_dir ${output_model}/logs \
--logging_strategy steps \
--logging_steps 10 \
--save_strategy steps \
--preprocessing_num_workers 10 \
--save_steps 20 \
--max_steps 800 \
--eval_steps 20 \
--save_total_limit 2000 \
--seed 42 \
--disable_tqdm false \
--ddp_find_unused_parameters false \
--block_size 2048 \
--report_to tensorboard \
--overwrite_output_dir \
--deepspeed scripts/training/ds_zero2_no_offload.json \
--ignore_data_skip true \
--bf16 \
--gradient_checkpointing \
--bf16_full_eval \
--ddp_timeout 18000000 \
| tee -a ${output_model}/train.log
# --resume_from_checkpoint ${output_model}/checkpoint-20400 \
调用
# github.com/FlagAlpha/Llama2-Chinese#%E5%85%A8%E9%87%8F%E5%8F%82%E6%95%B0%E5%BE%AE%E8%B0%83
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained('/root/llama/finetune_output/checkpoint-800',device_map='auto',torch_dtype=torch.float16)
model =model.eval()
tokenizer = AutoTokenizer.from_pretrained('/root/llama/finetune_output/checkpoint-800',use_fast=False)
tokenizer.pad_token = tokenizer.eos_token
input_ids = tokenizer(['<s>Human: 介绍一下中国\n</s><s>Assistant: '], return_tensors="pt",add_special_tokens=False).input_ids.to('cuda')
generate_input = {
"input_ids":input_ids,
"max_new_tokens":512,
"do_sample":True,
"top_k":50,
"top_p":0.95,
"temperature":0.3,
"repetition_penalty":1.3,
"eos_token_id":tokenizer.eos_token_id,
"bos_token_id":tokenizer.bos_token_id,
"pad_token_id":tokenizer.pad_token_id
}
generate_ids = model.generate(**generate_input)
text = tokenizer.decode(generate_ids[0])
print(text)