👉点击这里申请火山引擎VIP帐号,立即体验火山引擎产品>>>
背景信息
完整的训练类ChatGPT的代码:包括预训练模型下载、数据下载、InstructGPT训练过程和测试。
多种规模的模型:模型参数从1.3B到66B,既适合新手学习也可用于商用部署。
高效的训练:通过使用最新技术,如ZeRO和LoRA等技术改善训练过程,让训练过程更高效。
推理API:提供易于使用的推理API,方便进行对话式的交互测试。
软件要求
CUDA:使GPU能够解决复杂计算问题的计算平台。本文以11.4.152为例。
Python:编程语言,并提供机器学习库Numpy等。本文以3.8.10为例。
DeepSpeed:大模型训练工具。本文以0.10.2为例。
Tensorboard:机器学习实验可视化的工具。本文以2.14.0为例。
Transformers:一种神经网络架构,用于语言建模、文本生成和机器翻译等任务。本文以4.32.1为例。
Gradio:快速构建机器学习Web展示页面的开源Python库。本文以3.43.2为例。
使用说明
步骤一:准备环境
创建GPU计算型实例
请参考通过向导购买实例创建一台符合以下条件的实例:
基础配置:
计算规格:ecs.pni2.3xlarge
镜像:Ubuntu 20.04 with GPU Driver。
该镜像已默认安装Tesla 470.129.06版本的GPU驱动,适配的CUDA版本为11.4,需自行安装。
存储:云盘容量在100 GiB以上。
网络配置:勾选“分配弹性公网IP”。
创建成功后,在实例绑定的安全组中添加入方向规则:放行TCP 6006端口。具体操作请参见修改安全组访问规则。
安装并配置CUDA
登录实例。
依次执行以下命令,下载并安装CUDA 11.4。
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/cuda-ubuntu2004.pinsudo mv cuda-ubuntu2004.pin /etc/apt/preferences.d/cuda-repository-pin-600wget https://developer.download.nvidia.com/compute/cuda/11.4.4/local_installers/cuda-repo-ubuntu2004-11-4-local_11.4.4-470.82.01-1_amd64.debsudo dpkg -i cuda-repo-ubuntu2004-11-4-local_11.4.4-470.82.01-1_amd64.debsudo apt-key add /var/cuda-repo-ubuntu2004-11-4-local/7fa2af80.pubsudo apt-get updatesudo apt-get -y install cuda-11.4
执行以下命令,检查CUDA是否安装成功。
配置CUDA环境变量。
执行vim ~/.bashrc命令,打开配置文件。
按i进入编辑模式。
在文件末尾添加如下参数。
export CUDA_HOME=/usr/local/cuda-11.4export PATH=$PATH:$CUDA_HOME/binexport LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CUDA_HOME/lib64
按esc退出编辑模式,输入:wq并按Enter键,保存并退出文件。
执行source ~/.bashrc命令,使配置文件生效。
执行以下命令,查看CUDA。
创建虚拟环境
执行以下命令,下载Anaconda安装包。
执行以下命令,安装Anaconda。
持续按“Enter”键进行安装。
输入“yes”确认信息。
Anaconda的安装路径/root/anaconda3,请按“Enter”确认安装。
输入“yes”确定初始化Anaconda。
执行以下命令使配置文件生效。
创建一个名为“deepspeed”的虚拟环境,并指定该环境中的python版本为3.8。
执行conda create -n deepspeed python=3.8命令。
回显Proceed ([y]/n)?时输入“y”确认。
执行以下命令,激活虚拟环境。
安装DeepSpeed
执行以下命令,安装工具包。
执行以下命令,安装git并克隆DeepSpeed官方示例代码。
conda install gitgit clone https://github.com/microsoft/DeepSpeedExamples.git
依次执行以下命令,安装相应的依赖包。
cd DeepSpeedExamples/applications/DeepSpeed-Chat/pip3 install -r requirements.txt
执行以下命令,验证环境是否可用。
python>>>import torch>>>torch.cuda.is_available()
步骤二:选择预训练模型并整理数据集
选择预训练模型。
下载原始数据集并整理。本文采用数据集为医疗数据(Chinese-Medical-Question-Answering-System)。
使用git将原始数据集下载到本地。
git clone https://github.com/GongFuXiong/Chinese-Medical-Question-Answering-Systemcd Chinese-Medical-Question-Answering-System/ChineseMed_QaData# tree.├── 1.txt├── answers.csv # 回答文件├── dic4.txt├── model.txt└── questions.csv # 问题文件
整理数据集格式。
执行vim dataclean.py命令,打开dataclean.py文件。
按i进入编辑模式,添加如下内容。
import pandasdef transform_group(group):group.reset_index(inplace=True)group.drop('que_id', axis='columns', inplace=True)return group.to_dict(orient='records')main = pandas.read_csv('questions.csv', encoding='utf8')attributes = pandas.read_csv('answers.csv', index_col=0, encoding='utf8')attributes = attributes.groupby('que_id').apply(transform_group)attributes.name = "answers"main = main.merge(right=attributes,on='que_id',how='left',validate='m:1',copy=False,)main.to_json('medical_consultation.json', orient='records', indent=2, force_ascii=False)
按esc退出编辑模式,输入:wq并按Enter键,保存并退出文件。
{"que_id":43823757,"ques_content":"头痛,低烧,检查是新型隐球菌脑膜炎?头痛,低烧,检查是新型隐球菌脑膜炎。","answers":[{"ans_content":"口服抗病毒药物和感冒冲剂试试.有炎症还是应该加上抗生素。口服药物不见效的,建议输液治疗为好。在当地医生指导下使用。有痰的加上鲜竹沥口服试试。如果发烧还需要适当加上额外的退烧药物。"}]},{"que_id":33890331,"ques_content":"刚出生的小孩感冒了,鼻子不通怎么办?","answers":[{"ans_content":"你好,刚出生的小孩感冒了,鼻子不通,多与受寒有关。服用小儿氨酚黄那敏颗粒等等看看,注意体温变化,有发热时,要及时就医。"}]},
将数据上传至Hugging Face。
步骤三:创建并调用自定义的数据集类
登录实例。
创建自定义的数据集类。
执行以下命令,打开raw_datasets.py文件。
按i进入编辑模式,添加如下class类。
class MedicalConsultationDataset(PromptRawDataset):def __init__(self, output_path, seed, local_rank, dataset_name):super().__init__(output_path, seed, local_rank, dataset_name)self.dataset_name = "jisoul_medical_consultation"self.dataset_name_clean = "jisoul_medical_consultation"def get_train_data(self):from .data_utils import get_raw_dataset_split_indexprint(self.raw_datasets)dataset = self.raw_datasets["train"]index = get_raw_dataset_split_index(self.local_rank, self.output_path,self.dataset_name_clean,self.seed, "train_eval", "10,1", 0,len(dataset))dataset = Subset(dataset, index)return datasetdef get_eval_data(self):from .data_utils import get_raw_dataset_split_indexdataset = self.raw_datasets["test"]index = get_raw_dataset_split_index(self.local_rank, self.output_path,self.dataset_name_clean,self.seed, "train_eval", "10,1", 1,len(dataset))dataset = Subset(dataset, index)return datasetdef get_prompt(self, sample):if sample['ques_content'] is not None:return " Human: " + sample['ques_content'] + " Assistant:"return Nonedef get_chosen(self, sample):if sample['answers'][0]['ans_content'] is not None:return " " + sample['answers'][0]['ans_content']return Nonedef get_rejected(self, sample):print(f"Warning: dataset {self.dataset_name} does not include rejected response.")return Nonedef get_prompt_and_chosen(self, sample):if sample['ques_content'] is not None and sample['answers'] is not None:if sample['ques_content'] is not None and sample['answers'][0]['ans_content'] is not None:return " Human: " + sample['ques_content'] + " Assistant: " + sample['answers'][0]['ans_content']return Nonedef get_prompt_and_rejected(self, sample):print(f"Warning: dataset {self.dataset_name} does not include rejected response.")return None
按esc退出编辑模式,输入:wq并按Enter键,保存并退出文件。
调用对应的数据集类。
执行以下命令,打开data_utils.py文件。
按i进入编辑模式,添加如下条件。
elif "jisoul/medical_consultation" in dataset_name:return raw_datasets.MedicalConsultationDataset(output_path, seed, local_rank,dataset_name)
按esc退出编辑模式,输入:wq并按Enter键,保存并退出文件。
步骤四:初始化模型参数&微调模型
创建训练脚本。
执行以下命令,创建训练脚本。
按i进入编辑模式,添加如下内容。参数说明请参见附录二:训练脚本参数介绍。
#!/bin/bash# Copyright (c) Microsoft Corporation.# SPDX-License-Identifier: Apache-2.0# DeepSpeed Team# Note that usually LoRA needs to use larger learning rateOUTPUT=$1ZERO_STAGE=$2if [ "$OUTPUT" == "" ]; thenOUTPUT=./output/medical_consultationfiif [ "$ZERO_STAGE" == "" ]; thenZERO_STAGE=0fimkdir -p $OUTPUTdeepspeed --num_gpus 1 main.py \--data_path jisoul/medical_consultation \--model_name_or_path facebook/opt-125m \--gradient_accumulation_steps 4 \--zero_stage $ZERO_STAGE \--per_device_eval_batch_size 4 \--enable_tensorboard \--tensorboard_path $OUTPUT \--deepspeed --output_dir $OUTPUT
按esc退出编辑模式,输入:wq并按Enter键,保存并退出文件。
依次执行以下命令,运行脚本开始训练。
cd /root/DeepSpeedExamples/applications/DeepSpeed-Chat/training/step1_supervised_finetuningbash training_scripts/opt/single_gpu/run_medical_consultation.sh
步骤五:对模型进行调优和评估
执行以下命令,启动Tensorboard。
打开浏览器,访问http://<公网IP>:6006/,查看模型训练过程中的监控信息。
对模型进行评估。
执行以下命令,创建模型评估脚本。
按i进入编辑模式,修改文件内容。
--language Chinese \--model_name_or_path_baseline facebook/opt-125m \--model_name_or_path_finetune /root/DeepSpeedExamples/applications/DeepSpeed-Chat/training/step1_supervised_finetuning/output/medical_consultation/
按esc退出编辑模式,输入:wq并按Enter键,保存并退出文件。
执行以下命令,运行脚本。
步骤六:对微调后的模型进行部署和应用
安装Gradio和Transformers。
执行以下命令进行安装。
依次执行以下命令,查看是否安装成功。
pip3 list | grep gradiopip3 list | grep transformers
编写medical_consultation_gradio.py文件用于加载微调后的模型。
执行vim medical_consultation_gradio.py命令。
按i进入编辑模式,添加如下内容。
import gradio as grimport torchfrom transformers import AutoModelForCausalLM, AutoTokenizer, StoppingCriteria, StoppingCriteriaList, TextIteratorStreamerfrom threading import Threadtokenizer = AutoTokenizer.from_pretrained("/root/DeepSpeedExamples/applications/DeepSpeed-Chat/training/step1_supervised_finetuning/output/medical_consultation/")model = AutoModelForCausalLM.from_pretrained("/root/DeepSpeedExamples/applications/DeepSpeed-Chat/training/step1_supervised_finetuning/output/medical_consultation/")model = model.to('cuda:0')class StopOnTokens(StoppingCriteria):def __call__(self, input_ids: torch.LongTensor, scores: torch.FloatTensor, **kwargs) -> bool:stop_ids = [29, 0]for stop_id in stop_ids:if input_ids[0][-1] == stop_id:return Truereturn Falsedef predict(message, history):history_transformer_format = history + [[message, ""]]stop = StopOnTokens()messages = "".join(["".join(["\n<human>:"+item[0], "\n<bot>:"+item[1]]) #curr_system_message +for item in history_transformer_format])model_inputs = tokenizer([messages], return_tensors="pt").to("cuda")streamer = TextIteratorStreamer(tokenizer, timeout=10., skip_prompt=True, skip_special_tokens=True)generate_kwargs = dict(model_inputs,streamer=streamer,max_new_tokens=1024,do_sample=True,top_p=0.95,top_k=1000,temperature=1.0,num_beams=1,stopping_criteria=StoppingCriteriaList([stop]))t = Thread(target=model.generate, kwargs=generate_kwargs)t.start()partial_message = ""for new_token in streamer:if new_token != '<':partial_message += new_tokenyield partial_messagegr.ChatInterface(predict).queue().launch(share=True)
按esc退出编辑模式,输入:wq并按Enter键,保存并退出文件。
执行以下命令,运行脚本。
浏览器访问public URL(https://<公网IP>.gradio.live),如下图,表示成功使用Gradio构建生成式AI应用程序。
附录
附录一:如何选择预训练模型
考虑因素 | 说明 |
选择与任务和领域最相关的预训练模型 | 不同的模型可能在不同的任务上表现更好,因此需要根据您的具体需求选择适合的模型。 例如,对于自然语言处理任务,可以选择BERT、GPT等模型;对于图像处理任务,可以选择ResNet、Inception等模型。 |
了解预训练模型的性能和表现 | 查阅相关文献、研究论文或开发者文档,了解模型在不同任务和数据集上的表现。通常,可以使用常见的性能指标(如准确率、召回率、F1分数等)来评估模型的性能。 |
考虑预训练模型的规模和复杂度 | 大型模型通常具有更多的参数和更高的计算成本,但也可能具有更好的表现。如果您有足够的计算资源和数据量,可以选择规模较大的模型来获取更好的性能。 |
优先选择开放源代码和广泛可用的预训练模型 | 此类模型通常有更多的支持和社区贡献,可以更容易地获得文档、示例代码和工具。 |
考虑预训练模型的迁移学习性质 | 某些模型在不同任务和领域之间的迁移学习效果更好,可以更快地适应新任务。这对于数据量较小或计算资源受限的情况尤为重要。 |
了解模型的更新和维护情况 | 一些模型可能会定期更新,以改进性能或修复问题。选择有活跃维护和支持的模型,以确保您可以获得最新的改进和修复。 |
附录二:训练脚本参数介绍
参数 | 解释 |
--data_path | 数据集名称,默认从Hugging Face下载数据集文件 |
--model_name_or_path | 模型名称,默认从Hugging Face下载模型文件 |
--gradient_accumulation_steps | 开启梯度累积的step数 |
--zero_stage | Zero stage,可选0、1、2、3 |
--per_device_train_batch_size | 每块GPU运行的batch_size数 |
--enable_tensorboard | 打开Tensorboard |
--tensorboard_path | Tensorboard events的输出路径 |
--output_dir | 微调后的最终模型文件存储路径 |