Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

R2 でファインチューンした OpenAI モデルを作る

最終更新 Markdown で表示Agent セットアップ

このチュートリアルでは、OpenAI API と Cloudflare R2 を使い、ファインチューンモデル を作成します。

OpenAI API のこの機能では、独自の指示と回答例をもとに、OpenAI の各種大規模言語モデルからカスタムモデルを導出できます。指示と回答例はドキュメントに書き、これをファインチューンドキュメントと呼びます。このドキュメントは R2 に保存し、新しいファインチューンモデルを作るときに OpenAI API へ動的に渡します。

この機能を使うには、次の作業を行います。

  1. ファインチューンドキュメントを R2 にアップロードします。
  2. R2 のファイルを読み取り、OpenAI にアップロードします。
  3. そのドキュメントをもとに、新しいファインチューンモデルを作成します。
デモ

完成したアプリケーションのコードは、このチュートリアルの 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 アプリケーション内からファイルを保存・取得できます。新しい R2 バケットの作成には Wrangler を使います。

新しい 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.jsonlfine-tune-ai がバケット名)。<FILE_NAME> は、ローカルにあるファインチューンドキュメントのファイル名に置き換えます。

3. バケットを Worker にバインドする

バインディングは、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 アプリケーションを初期化する

Cloudflare Workers アプリケーション向けの軽量フレームワーク Hono を使います。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() は、エラーをレスポンスとして返すエラーハンドラーを定義します。

5. R2 のファイルを読み取り、OpenAI にアップロードする

この節では、ファイルアップロードを担当するルートと関数を定義します。

createFile では、Worker が R2 からファイルを読み取り、File オブジェクトに変換します。その後、OpenAI API でファイルをアップロードし、応答を返します。

GET /files ルートは、クエリパラメーター file 付きの GET リクエストを受け取ります。file は、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. ファインチューンジョブの状態を確認し、モデルを使う

アプリケーションを使うには、先にアップロードしたファイル名と一致する file クエリパラメーターを付けて /files にリクエストし、新しいファインチューンジョブを作成します。

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

ファイルのアップロード後、file_id クエリパラメーターを付けて /models にリクエストします。この値は、/files ルートが JSON で返す id と一致させてください。

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

最後に /jobs を開き、OpenAI 上のファインチューンジョブの状態を確認します。ジョブが完了すると fine_tuned_model の値が表示され、ファインチューンモデルが作成されたことがわかります。

ジョブ

ファインチューンモデルを使うには、OpenAI Playground を開きます。画面左上のドロップダウンから、ファインチューンモデルを選びます。

デモ

OpenAI の chat completions エンドポイントへの 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 でさらに作るには、チュートリアル を参照してください。

質問がある場合、支援が必要な場合、プロジェクトを共有したい場合は、Discord の Cloudflare Developer コミュニティに参加して、ほかの開発者や Cloudflare チームとつながれます。

役に立ちましたか?