跳转到内容
搜索文档

使用 R2 创建 OpenAI 微调模型

最后更新 查看 MarkdownAgent 设置

在本教程中,你将使用 OpenAI API 和 Cloudflare R2 创建微调模型

OpenAI API 中的这一功能允许你基于一组自定义指令和示例回答,从 OpenAI 的各种大语言模型中派生出定制模型。这些指令和示例回答写在一个文档中,称为微调文档(fine-tune document)。该文档将存储在 R2 中,并在创建新的微调模型时动态提供给 OpenAI 的 API。

要使用此功能,你需要完成以下任务:

  1. 将微调文档上传到 R2。
  2. 读取 R2 文件并上传到 OpenAI。
  3. 基于该文档创建新的微调模型。
Demo

要查看本应用的完整代码,请参阅本教程的 GitHub 仓库

前置条件

开始之前,请确保你已具备:

  • 拥有 R2 访问权限的 Cloudflare 账户。若尚未注册 Cloudflare 账户,请先注册,然后在 Cloudflare 仪表板中购买 R2。
  • OpenAI API 密钥。
  • 一份按 JSON Lines 格式组织的微调文档。可使用源码中的示例文档

1. 创建 Worker 应用

首先,使用 c3 CLI 创建新的 Cloudflare Workers 项目。

npm create cloudflare@latest -- finetune-chatgpt-model

进行设置时,请选择以下选项:

  • 对于 What would you like to start with?,选择 Hello World example
  • 对于 Which template would you like to use?,选择 Worker only
  • 对于 Which language do you want to use?,选择 TypeScript
  • 对于 Do you want to use git for version control?,选择 Yes
  • 对于 Do you want to deploy your application?,选择 No(部署前我们还会做一些修改)。

上述选项将创建 "Hello World" TypeScript 项目。

进入新创建的目录:

cd finetune-chatgpt-model

2. 将微调文档上传到 R2

接下来,将微调文档上传到 R2。R2 是一种键值存储,允许你在 Workers 应用中存储和检索文件。你将使用 Wrangler 创建新的 R2 存储桶。

要创建新的 R2 存储桶,请使用 wrangler r2 bucket create 命令。请确保你已登录 Cloudflare 账户。若尚未通过 Wrangler 登录,请使用 wrangler login 命令。

npx wrangler r2 bucket create <BUCKET_NAME>

<BUCKET_NAME> 替换为你想要的存储桶名称。存储桶名称必须为小写,且只能包含连字符。

接下来,使用 wrangler r2 object put 命令上传文件。

npx wrangler r2 object put <PATH> -f <FILE_NAME>

<PATH> 是要上传文件的存储桶与文件路径组合——例如 fine-tune-ai/finetune.jsonl,其中 fine-tune-ai 是存储桶名称。将 <FILE_NAME> 替换为微调文档的本地文件名。

3. 将存储桶绑定到 Worker

绑定(binding)是 Worker 与 R2 存储桶等外部资源交互的方式。

要将 R2 存储桶绑定到 Worker,请在 Wrangler 配置文件中添加以下内容。将 binding 属性更新为有效的 JavaScript 变量标识符。将 <YOUR_BUCKET_NAME> 替换为你在第 2 步中创建的存储桶名称:

{
	"r2_buckets": [
		{
			"binding": "MY_BUCKET", // <~ valid JavaScript variable name
			"bucket_name": "<YOUR_BUCKET_NAME>"
		}
	]
}
[[r2_buckets]]
binding = "MY_BUCKET"
bucket_name = "<YOUR_BUCKET_NAME>"

4. 初始化 Worker 应用

你将使用 Hono——一个用于构建 Cloudflare Workers 应用的轻量级框架。Hono 提供定义路由和中间件函数的接口。在项目目录中运行以下命令安装 Hono:

npm i hono

你还需要安装 OpenAI Node API 库。该库可在 Node.js 项目中便捷访问 OpenAI REST API。执行以下命令安装该库:

npm i openai

接下来,打开 src/index.ts 文件,将默认代码替换为以下代码。将 <MY_BUCKET> 替换为你在 Wrangler 配置文件中设置的绑定名称。

import { Context, Hono } from "hono";
import OpenAI from "openai";

type Bindings = {
	<MY_BUCKET>: R2Bucket
	OPENAI_API_KEY: string
}

type Variables = {
	openai: OpenAI
}

const app = new Hono<{ Bindings: Bindings, Variables: Variables }>()

app.use('*', async (c, next) => {
	const openai = new OpenAI({
		apiKey: c.env.OPENAI_API_KEY,
	})
	c.set("openai", openai)
	await next()
})

app.onError((err, c) => {
	return c.text(err.message, 500)
})

export default app;

在上述代码中,你首先导入所需的包并定义类型,然后将 app 初始化为新的 Hono 实例。使用 use 中间件函数,将 OpenAI API 客户端添加到所有路由的上下文中。该中间件允许你在任何路由处理程序中访问客户端。onError() 定义错误处理程序,将任何错误以 JSON 响应返回。

5. 读取 R2 文件并上传到 OpenAI

在本节中,你将定义负责处理文件上传的路由和函数。

createFile 中,Worker 从 R2 读取文件并将其转换为 File 对象。随后 Worker 使用 OpenAI API 上传文件并返回响应。

GET /files 路由监听带有查询参数 fileGET 请求,该参数表示 R2 中已上传微调文档的文件名。该函数使用 createFile 函数管理文件上传流程。

<MY_BUCKET> 替换为你在 Wrangler 配置文件中设置的绑定名称。

// New import added at beginning of file
import { toFile } from 'openai/uploads'

const createFile = async (c: Context, r2Object: R2ObjectBody) => {
	const openai: OpenAI = c.get("openai")

	const blob = await r2Object.blob()
	const file = await toFile(blob, r2Object.key)

	const uploadedFile = await openai.files.create({
		file,
		purpose: "fine-tune",
	})

	return uploadedFile
}

app.get('/files', async c => {
	const fileQueryParam = c.req.query("file")
	if (!fileQueryParam) return c.text("Missing file query param", 400)

	const file = await c.env.<MY_BUCKET>.get(fileQueryParam)
	if (!file) return c.text("Couldn't find file", 400)

	const uploadedFile = await createFile(c, file)
	return c.json(uploadedFile)
})

6. 创建微调模型

本节包含 GET /models 路由和 createModel 函数。createModel 函数负责指定详情并启动与 OpenAI 的微调流程。该路由处理创建新微调模型的传入请求。

const createModel = async (c: Context, fileId: string) => {
	const openai: OpenAI = c.get("openai");

	const body = {
		training_file: fileId,
		model: "gpt-4o-mini",
	};

	return openai.fineTuning.jobs.create(body);
};

app.get("/models", async (c) => {
	const fileId = c.req.query("file_id");
	if (!fileId) return c.text("Missing file ID query param", 400);

	const model = await createModel(c, fileId);
	return c.json(model);
});

7. 列出所有微调任务

本节描述 GET /jobs 路由及对应的 getJobs 函数。该函数与 OpenAI 的 API 交互以获取所有微调任务列表。该路由提供检索此信息的接口。

const getJobs = async (c: Context) => {
	const openai: OpenAI = c.get("openai");
	const resp = await openai.fineTuning.jobs.list();
	return resp.data;
};

app.get("/jobs", async (c) => {
	const jobs = await getJobs(c);
	return c.json(jobs);
});

8. 部署应用

创建 Worker 应用并添加所需函数后,即可部署应用。

部署前,你必须为应用设置 OPENAI_API_KEY 密钥。运行 wrangler secret put 命令:

npx wrangler secret put OPENAI_API_KEY

要将 Worker 应用部署到 Cloudflare 全球网络:

  1. 确保位于 Worker 项目目录中,然后运行 wrangler deploy 命令:
npx wrangler deploy
  1. Wrangler 将打包并上传你的代码。

  2. 应用部署后,Wrangler 会提供 Worker 的 URL。

9. 查看微调任务状态并使用模型

要使用你的应用,请向 /files 发起请求,并带上与之前上传文件名匹配的 file 查询参数以创建新的微调任务:

curl https://your-worker-url.com/files?file=finetune.jsonl

文件上传完成后,再向 /models 发起请求,传递 file_id 查询参数。该值应与 /files 路由返回的 JSON 中的 id 一致:

curl https://your-worker-url.com/models?file_id=file-abc123

最后,访问 /jobs 查看 OpenAI 中微调任务的状态。微调任务完成后,你可以看到 fine_tuned_model 值,表示已创建微调模型。

Jobs

访问 OpenAI Playground 以使用你的微调模型。在界面左上角的下拉菜单中选择你的微调模型。

Demo

可在对 OpenAI 聊天补全端点的任何 API 请求中使用它。例如,在以下代码示例中:

openai.chat.completions.create({
	messages: [{ role: "system", content: "You are a helpful assistant." }],
	model: "ft:gpt-4o-mini:my-org:custom_suffix:id",
});

后续步骤

要基于 Workers 构建更多内容,请参阅教程

如有疑问、需要帮助或想分享你的项目,请加入 Cloudflare 开发者社区 Discord,与其他开发者和 Cloudflare 团队交流。

这篇文档对您有帮助吗?