前言
近段时间Meta发布了LLaMA-3模型,并且效果看上去还不错,于是笔者对LLaMA-3相关的知识和技术进行了整理,主要包含LLaMA-3的技术原理以及微调方式总结。
技术原理
1. 模型改进
LLaMA-3目前包含8B和70B两种参数量的模型,其中每种参数量的模型都包含基础的预训练模型和经过指令微调的对话模型。相比于LLaMA-1和LLaMA-2,LLaMA-3的改进主要包含如下几个方面:
1.1 模型架构
-
分词器:LLaMA-3使用了一个词汇量为128K的分词器,更高效地编码语言,从而显著提高了模型的性能;
-
推理:基于对推理效率的考虑,使用了分组查询注意力(GQA);
-
上下文长度:将上下文的长度从4k调整为8k。
1.2 训练数据
-
训练数据量:LLaMA-3在预训练数据上使用了超过15T个token,比LLaMA-2使用的2T数据集大七倍,并且对代码生成数据和多语言数据的数量进行了调整;
-
数据质量:为了确保LLaMA-3能使用高质量的数据训练,因此设计了数据过滤的一些方法,包括启发式过滤器、NSFW过滤器、语义去重方法和文本分类器等;
-
数据配比:通过大量的实验验证了在最终预训练数据集中混合来自不同来源的数据的最佳方式。
1.3 指令微调
为了充分发挥预训练模型在对话模型中的潜力,使用了监督微调(SFT)、拒绝采样、近端策略优化(PPO)和直接策略优化(DPO)的结合。
2. 模型结构
Github上有一个从零开始实现LLaMA-3的项目,方便读者学习:https://github.com/naklecha/llama3-from-scratch/blob/main
**微调方法
**
了解了LLaMA-3的基本知识后,可能读者也想使用LLaMA-3模型的参数针对自己的应用场景进行微调,笔者整理了一些写的非常不错的Github项目,可以按照项目的Readme文件一步一步执行,从而训练属于自己的LLaMA-3模型。微调LLaMA-3的项目如下:
-
https://github.com/LlamaFamily/Llama-Chinese
-
https://github.com/yangjianxin1/Firefly
-
https://github.com/hiyouga/LLaMA-Factory
-
https://github.com/unslothai/unsloth
-
https://github.com/modelscope/swift
下面以https://github.com/LlamaFamily/Llama-Chinese项目为例,介绍如何基于已经预训练好的中文LLaMA-3进行微调:
(1)第一步,准备环境:
git clone https://github.com/LlamaFamily/Llama-Chinese.git``cd Llama-Chinese``pip install -r requirements.txt
(2)第二步,我们需要从如下地址下载中文LLaMA-3的模型参数:https://huggingface.co/FlagAlpha/Llama3-Chinese-8B-Instruct
(3)第三步,如果自己的应用场景比较特殊,并且能够收集到大量的数据,可以选择使用原始模型热启,继续进行预训练,从而更好地适应自己的场景,可以参考脚本./train/pretrain/pretrain.sh:
output_model=output_model``if [ ! -d ${output_model} ];then `` mkdir ${output_model}``fi``cp ./pretrain.sh ${output_model}``cp ./ds_config_zero*.json ${output_model}``export CUDA_HOME=/usr/local/cuda/``export NCCL_P2P_DISABLE=1`` ``deepspeed --include localhost:0,2 pretrain_clm.py \` `--config_name ../../model_config/Atom-100M/config.json \` `--tokenizer_name ../../model_config/Atom-100M \` `--train_files ../../data/wiki_zh/train_lm_task_0.csv \` `../../data/wiki_zh/train_lm_task_1.csv \` `--validation_files ../../data/wiki_zh/dev_lm_task.csv \` `--per_device_train_batch_size 32 \` `--per_device_eval_batch_size 32 \` `--do_train \` `--output_dir ${output_model} \` `--evaluation_strategy steps \` `--use_fast_tokenizer false \` `--max_eval_samples 500 \` `--learning_rate 1e-4 \` `--gradient_accumulation_steps 2 \` `--num_train_epochs 3 \` `--warmup_steps 5000 \` `--logging_dir ${output_model}/logs \` `--logging_strategy steps \` `--logging_steps 5 \` `--save_strategy steps \` `--preprocessing_num_workers 10 \` `--save_steps 100 \` `--eval_steps 5000000 \` `--save_total_limit 2000 \` `--seed 42 \` `--disable_tqdm false \` `--ddp_find_unused_parameters false \` `--block_size 1024 \` `--overwrite_output_dir \` `--report_to tensorboard \` `--run_name ${output_model} \` `--bf16 \` `--bf16_full_eval \` `--gradient_checkpointing \` `--deepspeed ./ds_config_zero3.json \` `--ignore_data_skip true \` `--ddp_timeout 18000000 \` `| tee -a ${output_model}/train.log
(4)第四步,收集一定规模的指令数据集进行微调,可以选择全量参数微调或者LoRA的方式微调,如果资源充足最好还是选择全量参数微调的方式,微调数据的构建格式可以参考该项目data目录下给出的数据集示例。
- 全量参数微调参考脚本./train/sft/finetune.sh:
output_model=save_folder``# 需要修改到自己的输入目录``if [ ! -d ${output_model} ];then `` mkdir ${output_model}``fi``cp ./finetune.sh ${output_model}``deepspeed --include localhost:1,0 finetune_clm.py \` `--model_name_or_path meta-llama/Llama-2-7b-chat-hf \` `--train_files ../../data/train_sft.csv \` `--validation_files ../../data/dev_sft.csv \` `../../data/dev_sft_sharegpt.csv \` `--per_device_train_batch_size 1 \` `--per_device_eval_batch_size 1 \` `--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 400 \` `--logging_dir ${output_model}/logs \` `--logging_strategy steps \` `--logging_steps 10 \` `--save_strategy steps \` `--preprocessing_num_workers 10 \` `--save_steps 20 \` `--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 ds_config_zero2.json \` `--ignore_data_skip true \` `--bf16 \` `--gradient_checkpointing \` `--bf16_full_eval \` `--ddp_timeout 18000000 \` `| tee -a ${output_model}/train.log
- LoRA微调参考脚本./train/sft/finetune_lora.sh:
output_model=save_folder``# 需要修改到自己的输入目录``if [ ! -d ${output_model} ];then `` mkdir ${output_model}``fi``export CUDA_HOME=/usr/local/cuda/``export NCCL_P2P_DISABLE=1``cp ./finetune.sh ${output_model}``deepspeed --include localhost:1,0 finetune_clm_lora.py \` `--model_name_or_path meta-llama/Llama-2-7b-chat-hf \` `--train_files ../../data/train_sft.csv \` `--validation_files ../../data/dev_sft.csv \` `../../data/dev_sft_sharegpt.csv \` `--per_device_train_batch_size 1 \` `--per_device_eval_batch_size 1 \` `--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 400 \` `--load_in_bits 4 \` `--lora_r 8 \` `--lora_alpha 32 \` `--target_modules q_proj,k_proj,v_proj,o_proj,down_proj,gate_proj,up_proj \` `--logging_dir ${output_model}/logs \` `--logging_strategy steps \` `--logging_steps 10 \` `--save_strategy steps \` `--preprocessing_num_workers 10 \` `--save_steps 20 \` `--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 ds_config_zero2.json \` `--ignore_data_skip true \` `--bf16 \` `--gradient_checkpointing \` `--bf16_full_eval \` `--ddp_timeout 18000000 \` `| tee -a ${output_model}/train.log
(5)训练完模型后,可能想尝试一下模型效果,就需要加载训练好的模型参数,然后使用模型进行推理。
- 全量参数微调后推理:
import torch``from transformers import AutoTokenizer, AutoModelForCausalLM``device_map = "cuda:0" if torch.cuda.is_available() else "auto"``model_name = "" # 保存的模型路径``model = AutoModelForCausalLM.from_pretrained(model_name,device_map=device_map,torch_dtype=torch.float16,load_in_8bit=True,trust_remote_code=True,use_flash_attention_2=True)``model =model.eval()``tokenizer = AutoTokenizer.from_pretrained(model_name,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``if torch.cuda.is_available():` `input_ids = 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)
- LoRA微调后推理:
import torch``from transformers import AutoTokenizer, AutoModelForCausalLM``from peft import PeftModel,PeftConfig``# 例如: finetune_model_path='Llama3-Chinese-7b-Chat-LoRA'``finetune_model_path = ''` `config = PeftConfig.from_pretrained(finetune_model_path)``# 例如: base_model_name_or_path='Llama-3-8b-chat'``tokenizer = AutoTokenizer.from_pretrained(config.base_model_name_or_path,use_fast=False)``tokenizer.pad_token = tokenizer.eos_token``device_map = "cuda:0" if torch.cuda.is_available() else "auto"``model = AutoModelForCausalLM.from_pretrained(config.base_model_name_or_path,device_map=device_map,torch_dtype=torch.float16,load_in_8bit=True,trust_remote_code=True,use_flash_attention_2=True)``model = PeftModel.from_pretrained(model, finetune_model_path, device_map={"": 0})``model =model.eval()``input_ids = tokenizer(['<s>Human: 介绍一下北京\n</s><s>Assistant: '], return_tensors="pt",add_special_tokens=False).input_ids``if torch.cuda.is_available():` `input_ids = 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)
总结
以上就是LLaMA-3相关的一些技术原理和微调方式总结,有需要的读者赶快学习起来吧。
除了这些,笔者还想再谈谈关于最近国内大模型打价格战这个问题。本来国内的大模型效果就不如OpenAI的GPTs,一直处于追赶的地步,结果效果还没达到比较领先的水平,现在就已经开始通过低价争抢用户,对于大厂还好,因为有比较雄厚的资金支持,但是对于初创公司可能就有点不太友好了,毕竟还没开始怎么赚钱,这么搞下去的话,可能过个2-3年,国内大多数大模型创业公司估计要寄了,虽然说这些行为是大公司为了赚钱采取的商业战略,但是可能对于国内大模型的发展有点不利,毕竟大模型最终还是要看效果才行,因此鼓励良性竞争才能让国内大模型有更好的发展。
如何系统的去学习大模型LLM ?
大模型时代,火爆出圈的LLM大模型让程序员们开始重新评估自己的本领。 “AI会取代那些行业
?”“谁的饭碗又将不保了?
”等问题热议不断。
事实上,抢你饭碗的不是AI,而是会利用AI的人。
继科大讯飞、阿里、华为
等巨头公司发布AI产品后,很多中小企业也陆续进场!超高年薪,挖掘AI大模型人才! 如今大厂老板们,也更倾向于会AI的人,普通程序员,还有应对的机会吗?
与其焦虑……
不如成为「掌握AI工具的技术人
」,毕竟AI时代,谁先尝试,谁就能占得先机!
但是LLM相关的内容很多,现在网上的老课程老教材关于LLM又太少。所以现在小白入门就只能靠自学,学习成本和门槛很高。
针对所有自学遇到困难的同学们,我帮大家系统梳理大模型学习脉络,将这份 LLM大模型资料
分享出来:包括LLM大模型书籍、640套大模型行业报告、LLM大模型学习视频、LLM大模型学习路线、开源大模型学习教程
等, 😝有需要的小伙伴,可以 扫描下方二维码领取🆓↓↓↓
一、LLM大模型经典书籍
AI大模型已经成为了当今科技领域的一大热点,那以下这些大模型书籍就是非常不错的学习资源。
二、640套LLM大模型报告合集
这套包含640份报告的合集,涵盖了大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。(几乎涵盖所有行业)
三、LLM大模型系列视频教程
四、LLM大模型开源教程(LLaLA/Meta/chatglm/chatgpt)
LLM大模型学习路线 ↓
阶段1:AI大模型时代的基础理解
-
目标:了解AI大模型的基本概念、发展历程和核心原理。
-
内容:
- L1.1 人工智能简述与大模型起源
- L1.2 大模型与通用人工智能
- L1.3 GPT模型的发展历程
- L1.4 模型工程
- L1.4.1 知识大模型
- L1.4.2 生产大模型
- L1.4.3 模型工程方法论
- L1.4.4 模型工程实践
- L1.5 GPT应用案例
阶段2:AI大模型API应用开发工程
-
目标:掌握AI大模型API的使用和开发,以及相关的编程技能。
-
内容:
- L2.1 API接口
- L2.1.1 OpenAI API接口
- L2.1.2 Python接口接入
- L2.1.3 BOT工具类框架
- L2.1.4 代码示例
- L2.2 Prompt框架
- L2.3 流水线工程
- L2.4 总结与展望
阶段3:AI大模型应用架构实践
-
目标:深入理解AI大模型的应用架构,并能够进行私有化部署。
-
内容:
- L3.1 Agent模型框架
- L3.2 MetaGPT
- L3.3 ChatGLM
- L3.4 LLAMA
- L3.5 其他大模型介绍
阶段4:AI大模型私有化部署
-
目标:掌握多种AI大模型的私有化部署,包括多模态和特定领域模型。
-
内容:
- L4.1 模型私有化部署概述
- L4.2 模型私有化部署的关键技术
- L4.3 模型私有化部署的实施步骤
- L4.4 模型私有化部署的应用场景
这份 LLM大模型资料
包括LLM大模型书籍、640套大模型行业报告、LLM大模型学习视频、LLM大模型学习路线、开源大模型学习教程
等, 😝有需要的小伙伴,可以 扫描下方二维码领取🆓↓↓↓