网站怎么备案啊,网站的专题怎么做,附近室内设计培训学校,还是正式公司好该博客是我根据自己学习过程中的思考与总结来写作的#xff0c;由于初次学习#xff0c;可能会有错误或者不足的地方#xff0c;望批评与指正。 1. 安装
1.1 LLaMA-Factory安装
安装可以参考官方 readme #xff08;https://github.com/hiyouga/LLaMA-Factory/blob/main/… 该博客是我根据自己学习过程中的思考与总结来写作的由于初次学习可能会有错误或者不足的地方望批评与指正。 1. 安装
1.1 LLaMA-Factory安装
安装可以参考官方 readme https://github.com/hiyouga/LLaMA-Factory/blob/main/README_zh.md
懒得跳转网页的也可以直接复制下面的内容
git clone https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
pip install -e .1.2 下载LLM
从huggingface或者镜像源https://hf-mirror.com/下载想要微调的模型。
PS可以不用下载到本地不过因为我们服务器不允许挂梯子而且担心网络不稳定所以我都是下载到本地的。
2. 准备训练数据
这应该是用LLaMA-Factory微调整个大模型中为数不多的需要写代码的部分。数据集的说明请参考https://github.com/hiyouga/LLaMA-Factory/blob/main/data/README_zh.md。
由于我们是采用SFT的方式来构建数据集所以简单点可以直接看https://github.com/hiyouga/LLaMA-Factory/blob/main/data/alpaca_zh_demo.json 这个json文件的格式将数据集构建为上述json格式即可即
[{instruction: 人类指令必填,input: 人类输入选填,output: 模型回答必填,system: 系统提示词选填,history: [[第一轮指令选填, 第一轮回答选填],[第二轮指令选填, 第二轮回答选填]]}
]数据为一个列表列表中每个元素为一个字典。如果是单轮对话则无需 history。
当数据集构建完成后可以放在data/路径下也可以放在其他位置。
3. 配置dataset_info.json文件
将数据集构建完成后需要在data/目录下找到dataset_info.json文件并在这个文件中配置数据集的信息个人觉得这一步类似于django中的注册url。
假设构建的数据集名字为input_data.json那么在dataset_info.json需要加如下的字典
数据集名称: {file_name: input_data.json,columns: {prompt: instruction,query: input,response: output}},这里数据集名称可以自行定义只需要在后续写yaml文件时把这个名称写进去就行。这里的file_name要与数据集的名称相同如果文件放在了data/路径下只需要数据集名称就行而如果文件没有放在该路径下则需要在这里指定路径。
4. 微调模型
微调模型可以选用启动网页服务来进行微调执行以下命令启动网页服务
llamafactory-cli webui当然我更喜欢用配置文件的方式来微调模型。新建一个 yaml 文件假设名为train_qwen_lora_sft.yaml可以在该文件中定义具体的训练设置。当然很多朋友不知道有哪些参数需要设置可以查看github中的demo进行配置https://github.com/hiyouga/LLaMA-Factory/blob/main/examples/train_lora/llama3_lora_sft.yaml具体而言
### model
model_name_or_path: Qwen2-1.5B-Instruct### method
stage: sft
do_train: true
finetuning_type: lora
lora_target: all### dataset
dataset: input_data
template: qwen
cutoff_len: 1024
max_samples: 1000
overwrite_cache: true
preprocessing_num_workers: 16### output
output_dir: saves/llama3-8b/lora/sft
logging_steps: 10
save_steps: 500
plot_loss: true
overwrite_output_dir: true### train
per_device_train_batch_size: 1
gradient_accumulation_steps: 8
learning_rate: 1.0e-4
num_train_epochs: 3.0
lr_scheduler_type: cosine
warmup_ratio: 0.1
bf16: true
ddp_timeout: 180000000### eval
val_size: 0.1
per_device_eval_batch_size: 1
eval_strategy: steps
eval_steps: 500这里要注意的有几个参数
model_name_or_path: 这个是需要微调的模型如果下载到了本地则指定本地路径如果没有下载到本地就在huggingface上找路径。dataset这个是数据集的名称即在第三步中配置的数据集名称。这里支持多个数据集进行微调如果要设置多个数据集那么用逗号隔开即数据集名称1,数据集名称2。template: 用的什么模型就用什么模板比如用的通义千问就设置qwen。template的名字可以参考https://zhuanlan.zhihu.com/p/689333581。output_dir这里是输出的文件路径需要注意的是由于采用的是LORA进行微调所以这里输出的文件是LORA的参数在实际部署的时候最好将LORA参数和原模型参数进行合并。具体合并的方式下一步会讲。num_samples如果想用数据集中所有数据进行训练这个值可以设置的很大比如999999否则这个值如果小于数据集大小的话只会选择部分数据进行训练。learning_rate不只是learning_rate所有的数字都可能会面临一个问题即如果采用科学计数法如1e-6会报错详见https://blog.csdn.net/qq_35357274/article/details/143615453解决方式就是用1.0e-6或者0.000001。eval如果不需要验证这一坨其实可以不需要的。
微调的时候有可能显卡被人占用了需要指定在哪几张卡上进行微调所以用如下的命令进行微调
CUDA_VISIBLE_DEVICES0 llamafactory-cli train yaml路径微调完成后在output_dir路径下会有个文件夹即LORA的参数文件接着需要合并文件。
5. 合并文件
合并文件的yaml文件注意不是训练的yaml文件需要新建一个我最开始以为两个是一个文件可以参考https://github.com/hiyouga/LLaMA-Factory/blob/main/examples/merge_lora/qwen2vl_lora_sft.yaml具体而言
### Note: DO NOT use quantized model or quantization_bit when merging lora adapters### model
model_name_or_path: Qwen/Qwen2-VL-7B-Instruct
adapter_name_or_path: saves/qwen2_vl-7b/lora/sft
template: qwen2_vl
finetuning_type: lora### export
export_dir: models/qwen2_vl_lora_sft
export_size: 2
export_device: cpu
export_legacy_format: falsemodel_name_or_path如上面一样是原始模型的路径。adapter_name_or_pathLORA的参数位置即第四步中output_dir的路径。export_dir合并后的文件路径。export_size单个文件的最大大小GB。
运行命令
llamafactory-cli export yaml路径6. 部署
我这里选用的vLLM作为部署框架有两种部署方式。如果是自己做实验的话可以离线部署如果是上线的话建议用在线部署。
6.1 离线部署
离线部署即自己写个类或者方法调用微调后的模型代码如下
import os
import torch
os.environ[CUDA_VISIBLE_DEVICES] 2
from vllm import LLM, SamplingParamsclass Detect:def __init__(self, model_path, temperature0.8, top_p0.95)::param model_path: str:param temperature: float取值范围: [0, ∞]- 当 temperature 设为 0 时模型总是选择具有最高概率的单词这会导致生成的结果非常确定性缺乏随机变化。- 当 temperature 接近 1 时模型的选择更加随机这可以增加生成文本的多样性。- 高于 1 的值可能会导致生成的文本更加随机有时可能失去连贯性- 注: 如果生成的内容太多就调低这个值:param top_p: float取值范围: (0, 1]- top_p 参数表示从候选词汇中选取累积概率总和达到或超过 p 的词汇集合然后从中随机选取下一个词汇。这种方式可以减少 temperature 为高值时可能出现的无意义输出。- 当 top_p 设置为接近 1 的值时几乎所有的候选词汇都会被考虑这类似于 temperature 接近 1 的情况。- 当 top_p 设置为较低值时只有最有可能出现的几个词汇会被选中这样可以减少输出的不确定性。- 注: 如果生成的内容太多就调低这个值if not isinstance(temperature, (int, float)) or not isinstance(top_p, (int, float)):raise ValueError(变量 temperature 和 top_p 必须为整型或浮点数)if temperature 0:raise ValueError(变量 temperature 的取值范围为[0, ∞])if top_p 0 or top_p 1:raise ValueError(变量 top_p 的取值范围为(0, 1])self.template hiself.llm LLM(modelmodel_path, dtypetorch.bfloat16)self.tokenizer self.llm.get_tokenizer()self.sampling_params SamplingParams(temperaturetemperature, top_ptop_p)def detect(self, input_texts):prompts []for input_text in input_texts:prompt [{role: system, content: self.template},{role: user, content: input_text \n输出}]prompts.append(prompt)prompts self.tokenizer.apply_chat_template(prompts, add_generation_promptTrue, tokenizeFalse)outputs self.llm.generate(prompts, self.sampling_params)return [output.outputs[0].text for output in outputs]
这里model_path即微调后的模型路径。还需注意的是如果服务器足够垃圾有可能self.llm LLM(modelmodel_path, dtypetorch.bfloat16)会报错因为老的服务器有可能不支持bfloat16改为float16就行。
离线的代码如果部署到线上在多线程调用的情况下很有可能会触发cuda显存不够的错误所以部署项目的时候通常采用在线部署的方式。
6.2 在线部署
与离线部署不同采用在线部署首先需要启动服务。
CUDA_VISIBLE_DEVICES2 python3 -m vllm.entrypoints.openai.api_server --model model_path --served-model-name qwen --trust-remote-code --host 0.0.0.0 --port 8080 --dtype bfloat16这里model_path是微调后的模型路径host是主机默认为localhost如果项目是在容器内的话这里需要自行设置IP地址port是端口号默认为8000。
当启动服务后会有这么一个提示信息 这个IP地址即服务的地址就可以采用访问http的形式来调用模型。
有的人会使用curl http的形式来调用接口我选用的是采用python脚本实现具体代码如下
from openai import OpenAIdef detect(input_texts, template, porthttp://localhost:8000/v1, temperature0.8, top_p0.95)::param input_texts: list输入文本:param template: str提示模板:param port: str端口号:param temperature: float取值范围: [0, ∞]- 当 temperature 设为 0 时模型总是选择具有最高概率的单词这会导致生成的结果非常确定性缺乏随机变化。- 当 temperature 接近 1 时模型的选择更加随机这可以增加生成文本的多样性。- 高于 1 的值可能会导致生成的文本更加随机有时可能失去连贯性- 注: 如果生成的内容太多就调低这个值:param top_p: float取值范围: (0, 1]- top_p 参数表示从候选词汇中选取累积概率总和达到或超过 p 的词汇集合然后从中随机选取下一个词汇。这种方式可以减少 temperature 为高值时可能出现的无意义输出。- 当 top_p 设置为接近 1 的值时几乎所有的候选词汇都会被考虑这类似于 temperature 接近 1 的情况。- 当 top_p 设置为较低值时只有最有可能出现的几个词汇会被选中这样可以减少输出的不确定性。- 注: 如果生成的内容太多就调低这个值:return:if not isinstance(temperature, (int, float)) or not isinstance(top_p, (int, float)):raise ValueError(变量 temperature 和 top_p 必须为整型或浮点数)if temperature 0:raise ValueError(变量 temperature 的取值范围为[0, ∞])if top_p 0 or top_p 1:raise ValueError(变量 top_p 的取值范围为(0, 1])openai_api_key EMPTYopenai_api_base portclient OpenAI(api_keyopenai_api_key,base_urlopenai_api_base,)outputs []for input_text in input_texts:chat_response client.chat.completions.create(modelqwen,messages[{role: system, content: template},{role: user, content: input_text},],temperaturetemperature,top_ptop_p,)outputs.append(chat_response.choices[0].message.content)return outputs这个代码里面port即上面控制台信息中返回的IP地址传入即可。
7. 参考
[1] https://github.com/hiyouga/LLaMA-Factory/tree/main [2] llama-factory SFT系列教程 (二)大模型在自定义数据集 lora 训练与部署 [3] VLLM 把模型部署成 openai API server 形式 [4] https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct [5] https://github.com/echonoshy/cgft-llm/blob/master/llama-factory/README.md