通义千问Qwen-72B-Chat基于PAI的低代码微调部署实践

通义千问Qwen-72B-Chat基于PAI的低代码微调部署实践

通义千问Qwen-72B-Chat基于PAI的低代码微调部署实践

熊兮、求伯、一耘  2024年01月11日 10:00 浙江

01

引言

通义千问-72B(Qwen-72B)是阿里云研发的通义千问大模型系列的720亿参数规模模型。Qwen-72B的预训练数据类型多样、覆盖广泛,包括大量网络文本、专业书籍、代码等。Qwen-72B-Chat是在Qwen-72B的基础上,使用对齐机制打造的基于大语言模型的AI助手。

阿里云人工智能平台PAI是面向开发者和企业的机器学习/深度学习平台,提供AI开发全链路服务。快速开始(PAI-QuickStart)是阿里云人工智能平台PAI的产品组件,它集成了国内外 AI 开源社区中优质的预训练模型,支持零代码和 SDK 的方式实现从训练到部署再到推理的全过程,大大简化了模型的开发和部署,为开发者和企业用户带来了更快、更高效、更便捷的 AI 开发和应用体验。

本文将以 Qwen-72B-Chat 为例,介绍如何通过PAI平台的快速开始(PAI-QuickStart)部署和微调千问大模型。

02

运行环境要求

本示例目前仅支持在阿里云乌兰察布地域,使用灵骏集群环境运行。

资源配置要求:GPU 推荐使用 GU108(80GB),推理需要4卡及以上资源,微调需要4机32卡及以上资源。

阿里云 PAI 灵骏智算服务资源开通和管理请参考官网文档:灵骏智算资源的购买开通

https://help.aliyun.com/zh/pai/user-guide/create-and-manage-intelligent-computing-lingjun-resources

03

通过PAI控制台使用模型

开发者可以在 PAI 控制台的“快速开始”入口,找到 Qwen-72B-Chat 的模型,Qwen-72B-Chat 的模型卡片如下图所示:

www.zeeklog.com  - 通义千问Qwen-72B-Chat基于PAI的低代码微调部署实践

模型部署和调用

通过“模型部署”入口,用户选择使用的灵骏资源信息,点击部署按钮,即可将模型部署到 PAI-EAS 推理服务平台。

www.zeeklog.com  - 通义千问Qwen-72B-Chat基于PAI的低代码微调部署实践

通过部署的在线服务的详情页,用户可以查看服务访问地址(Endpoint)和访问凭证(Token),然后用于调用推理HTTP API。使用 cURL 调用推理服务的示例如下。

注意,因为模型较大,加载时间较长,用户可以在服务启动之后,通过以下的“查看模型列表”API查看服务当前加载完成的模型。

  • # 请注意替换为使用服务的Endpoint和Tokenexport API_ENDPOINT="<ENDPOINT>"export API_TOKEN="<TOKEN>" # 查看模型listcurl $API_ENDPOINT/v1/models \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $API_TOKEN" # 调用通用的文本生成APIcurl $API_ENDPOINT/v1/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $API_TOKEN" \ -d '{      "model": "qwen-72b-chat", "prompt": "San Francisco is a", "max_tokens": 256, "temperature": 0, "stop": ["<|im_end|>", "<|im_start|>"]}' # 调用对话APIcurl $API_ENDPOINT/v1/chat/completions \ -H "Authorization: Bearer $API_TOKEN" \ -H "Content-Type: application/json" \ -d '{      "model": "qwen-72b-chat", "messages": [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "介绍一下上海的历史"} ], "stop": ["<|im_end|>", "<|im_start|>"] }'

用户也可以通过 openai SDK 的方式进行调用,首先需要安装调用SDK:

# 安装服务调用SDK

通过 SDK 调用服务的示例如下,请注意替换代码中使用的访问地址和访问凭证。

  • import openai # 请使用服务详情页获取的访问地址(ENDPOINT)和访问凭证(TOKEN)替换以下代码的配置。openai.api_key = "<TOKEN>"openai.base_url = "<ENDPOINT>" + "/v1" # 调用对话APIcompletion = openai.chat.completions.create( model="qwen-72b-chat", temperature=0.0, top_p=0.8, frequency_penalty=0.0, messages=[{"role": "user", "content": "请介绍下你自己。"}], stop=["<|im_end|>", "<|im_start|>"], # stream=True,)# 打印输出内容print(completion.choices[0].message.content)

模型微调训练

PAI-QuickStart 支持的 Qwen-72B-Chat 的全量参数微调基于 Megatron-LM 的训练流程,支持了数据并行、算子拆分、流水并行、序列并行、选择性激活重算、Zero显存优化等技术,大幅提升大模型分布式训练效率。在这一算法组件中,我们提前对模型Checkpoint进行了切分,适配多机多卡环境训练,开发者只需根据格式要求准备训练集和验证集,配置任务超参数或是使用模型预置的默认超参,就可以一键拉起训练任务。

微调算法的超参支持如下:

www.zeeklog.com  - 通义千问Qwen-72B-Chat基于PAI的低代码微调部署实践

通过模型详情的“微调训练”入口,我们可以根据实际需求调整超参数,例如learning_rate、sequence_length、train_iters等,如下所示:

www.zeeklog.com  - 通义千问Qwen-72B-Chat基于PAI的低代码微调部署实践

算法的训练和验证数据集接受Json格式输入,每条数据由问题、答案组成,分别用"instruction"和"output"字段表示,例如:

  • [ { "instruction": "写一首以“寓居夜感”为题的诗:", "output": "独坐晚凉侵,客窗秋意深。风沙疑化雾,夜气欲成霖。家务劳人倦,浓茶代酒斟。哀鸿鸣四野,一并助长吟。" }, { "instruction": "写一首以“次答友人思乡诗”为题的诗:", "output": "阅尽沧桑万事空,何如归卧夕阳中。并州最是伤心地,四十馀年噩梦同。" }]

用户可以通过将数据准备到到OSS Bucket上,然后在“数据集”配置中选择使用。

www.zeeklog.com  - 通义千问Qwen-72B-Chat基于PAI的低代码微调部署实践

当前算法仅支持使用灵骏资源进行训练,在提交训练作业之前,用户需要配置使用的灵骏资源ID。

在完成以上配置之后,点击“训练”按钮,PAI-QuickStart自动跳转到模型训练页面,并且开始进行训练,用户可以查看训练任务状态和训练日志,如下所示:

www.zeeklog.com  - 通义千问Qwen-72B-Chat基于PAI的低代码微调部署实践

在训练结束后,可以在输出路径的OSS Bucket中查看每次保存的Checkpoint模型切片,如下所示:

www.zeeklog.com  - 通义千问Qwen-72B-Chat基于PAI的低代码微调部署实践

用户可以根据实际情况,选择最合适的Checkpoint进行推理和部署,具体流程参见,本文不再赘述。

04

通过PAI Python SDK使用模型

PAI-QuickStart 提供的预训练模型,也支持通过PAI Python SDK进行调用,详细流程可以参考文档:使用预训练模型 — PAI Python SDK。

https://alipai.readthedocs.io/zh/latest/user-guide/pretrained-model.html

我们首先需要安装和配置PAI Python SDK,开发者可以在命令行执行以下代码完成。

# 安装PAI Python SDK

如何获取 SDK 配置所需的访问凭证(AccessKey),PAI 工作空间等信息请参考文档:如何安装和配置PAI Python SDK

https://help.aliyun.com/zh/pai/user-guide/install-and-configure-pai-python-sdk

模型部署和调用

通过 PAI Python SDK 提供的便利方法,开发者通过数行代码,即可将 Qwen-72B-Chat 模型部署到 PAI-EAS,创建一个在线推理服务。

from pai.session import  get_default_session

模型服务的调用,请参考以上章节,在此不再赘述。

模型微调训练

通过 SDK 获取 PAI QuickStart 提供的预训练模型之后,我们可以查看模型配置的微调算法,包括算法支持的超参配置以及输入输出数据。

from pai.model import RegisteredModel

目前,Qwen-72B-Chat 提供的微调算法仅支持灵骏资源,开发者需要通过 PAI 的控制台页面,查看当前的资源配额 ID,设置训练任务使用的资源信息。同时在提交训练作业之前,用户可以根据算法的超参支持,配置合适的训练任务超参。

# 配置训练作业使用的灵骏资源配额ID

微调算法支持3个输入,分别为:

model:Qwen-72b-Chat预训练模型

train:微调使用的训练数据集

validation:微调使用的验证数据集

# 查看模型微调算法的使用的输入信息

开发者可以参考以上的训练数据格式准备数据,然后将train和validation输入替换为自己的训练和验证数据集,即可轻松得提交模型微调训练作业。通过 SDK 打印的训练作业链接,用户可以在 PAI 的控制台上查看训练进度详情以及日志信息。

from pai.common.oss_utils import download

05

结论

阿里云 PAI-QuickStart 提供了对 Qwen-72B-Chat 模型微调训练和部署开箱即用的体验,简化了 AI 开发流程,帮助开发者和企业用户使用大语言模型加速创新,创造更多的价值。

相关资料

PAI 快速开始:

https://help.aliyun.com/zh/pai/user-guide/quick-start-overview

通义千问系列模型:

https://modelscope.cn/organization/qwen

PAI Python SDK:

https://github.com/aliyun/pai-python-sdk

阿里云PAI灵骏智算服务:

https://www.aliyun.com/product/bigdata/learn/pailingjun

/ END /

Read more

深入理解 Proxy 和 Object.defineProperty

在JavaScript中,对象是一种核心的数据结构,而对对象的操作也是开发中经常遇到的任务。在这个过程中,我们经常会使用到两个重要的特性:Proxy和Object.defineProperty。这两者都允许我们在对象上进行拦截和自定义操作,但它们在实现方式、应用场景和灵活性等方面存在一些显著的区别。本文将深入比较Proxy和Object.defineProperty,包括它们的基本概念、使用示例以及适用场景,以帮助读者更好地理解和运用这两个特性。 1. Object.defineProperty 1.1 基本概念 Object.defineProperty 是 ECMAScript 5 引入的一个方法,用于直接在对象上定义新属性或修改已有属性。它的基本语法如下: javascript 代码解读复制代码Object.defineProperty(obj, prop, descriptor); 其中,obj是目标对象,prop是要定义或修改的属性名,descriptor是一个描述符对象,用于定义属性的特性。 1.2 使用示例 javascript 代码解读复制代码//

By Ne0inhk

Proxy 和 Object.defineProperty 的区别

Proxy 和 Object.defineProperty 是 JavaScript 中两个不同的特性,它们的作用也不完全相同。 Object.defineProperty 允许你在一个对象上定义一个新属性或者修改一个已有属性。通过这个方法你可以精确地定义属性的特征,比如它是否可写、可枚举、可配置等。该方法的使用场景通常是需要在一个对象上创建一个属性,然后控制这个属性的行为。 Proxy 也可以用来代理一个对象,但是相比于 Object.defineProperty,它提供了更加强大的功能。使用 Proxy 可以截获并重定义对象的基本操作,比如访问属性、赋值、函数调用等等。在这些操作被执行之前,可以通过拦截器函数对这些操作进行拦截和修改。因此,通过 Proxy,你可以完全重写一个对象的默认行为。该方法的使用场景通常是需要对一个对象的行为进行定制化,或者需要在对象上添加额外的功能。 对比 以下是 Proxy 和 Object.defineProperty 的一些区别对比: 方面ProxyObject.defineProperty语法使用 new Proxy(target,

By Ne0inhk