- Datasets とは何で、コンソール(
app.fireworks.ai/dashboard/datasets)と firectl・REST API のどこで管理するか - SFT・DPO/ORPO・RFT が使う JSONL は、互換性のない 3 つの別スキーマであること
- API 単発 150MB・UI 500MB 未満・例数 3〜300 万・例数×エポック 300 万以下という、混同しやすい 4 つの上限の違い
- 150MB を超えるファイルを送るときの「create → getUploadEndpoint → 署名付き URL へ PUT → validateUpload」という 4 段フロー
- データセットが学習ジョブ(第 11 章)にどうつながるか、その手前で確認しておくべきこと
これは何か
Dataset(データセット)とは、モデルを学習させるために使える、学習サンプルの不変な集合(immutable set of training examples)のことである。学習を始めるには、学習方法(SFT・DPO/ORPO・RFT)にかかわらず、まずこのデータセットという単位でプラットフォームに登録する必要がある。第 9 章までの Serverless・Deployments が「モデルをどう動かすか」の章だったのに対し、この章と第 11 章は「モデルをどう自分の仕事に合わせるか」の章であり、Datasets はその材料を用意する入口にあたる。
ここで出てくる 3 つの学習方法を 1 文ずつ定義しておく。SFT(教師ありファインチューニング、Supervised Fine-Tuning)は正解の応答例を見せてそのとおりに真似させる方式、DPO・ORPO(選好最適化)は良い応答と悪い応答の対を見せて優劣を教える方式、RFT(強化ファインチューニング、Reinforcement Fine-Tuning)は正解の応答例を用意しなくてよく(入れても構わない)、プロンプトと採点役(評価器)だけでモデルに試行錯誤させる方式である。どれを選ぶかの詳しい基準は第 11 章で扱うが、この 3 方式が要求する学習データの形が全く違う、という点がこの章の主題になる。
コンソール(app.fireworks.ai)では、コンソールの dataset タブから Create Dataset ボタンでウィザードを開き、個々のデータセットは app.fireworks.ai/dashboard/datasets/<DATASET_ID> というページを持つ。データセットテーブルからは、ファイル単位のダウンロードと「Download All」による一括ダウンロードもできる。API・CLI から直接触ることも多く、REST では POST https://api.fireworks.ai/v1/accounts/{account_id}/datasets(作成)と POST .../datasets/{dataset_id}:upload(アップロード)の 2 つのエンドポイントが基本になり、CLI では firectl dataset create / list / get / download / delete の一群のサブコマンドで同じ操作ができる。
いつ使うのか
データセットを新しく用意する場面は、大きく分けて次の 3 通りである。
- 手元の会話ログ・Q&A・評価済み出力を JSONL にまとめてアップロードする — 最も基本的な使い方で、この章のハンズオンもこの経路を扱う
- 既に登録済みのデータセットから一部だけを切り出して新しいデータセットを作る —
sourceDatasetId+filter(SQL の WHERE 句に似た条件式)を指定すると、既存データセットをフィルタした派生データセットをプラットフォーム側で作れる - 本番トラフィックのトレースから学習データセットを起こす —
firectl dataset createの--trace-from-model-idに対象モデルを、期間指定のフラグ(--start-time・--end-time)に範囲を渡すと、本番リクエストの実績から学習データを組み立てられる
データをどこに置くかという観点では、通常のアップロード・派生生成・BYOB(Bring Your Own Bucket、自前のクラウドバケットを参照させる方式)の 3 択があり、性質がはっきり異なる。
| 観点 | 通常アップロード(userUploaded) | 派生生成(sourceDatasetId + filter) | BYOB(externalUrl) |
|---|---|---|---|
| データの置き場所 | Fireworks 管理ストレージ(GCS)にコピーされる | 同じく Fireworks 管理ストレージ | 自分の GCS / AWS S3 / Azure Blob。コピーされない |
| 作り方 | ファイルをそのままアップロード | 既存データセットを条件式で絞り込む | --external-url gs://... で外部 URI を登録 |
| 向く場面 | 初めてのデータセット・少量データ | 大きな元データから用途別に部分集合を作りたいとき | データを Fireworks に一切コピーしたくない厳格な要件 |
BYOB はジョブの実行中だけ元のバケットを in-place で読み、データセットのコピーを持たない。ジョブが終わったらバケットへのアクセス権を剥奪する運用が前提になる。反対に通常アップロードでは、データセット自体はジョブ後も残るので、不要になったら自分で削除する必要がある(この章のハンズオンで実際に削除まで行う)。
仕組み(1)— JSONL は互換性のない 3 つのスキーマに分かれる
Datasets はどの学習方法(SFT / DPO・ORPO / RFT)でも同じ JSONL(1 行 = 1 つの完全な JSON オブジェクト)というファイル形式を使う。しかし行の中身のスキーマは 3 つとも別物で、ルート直下に来るキーからして違う。ここを混同すると、SFT 用に作ったファイルを DPO ジョブにそのまま投げてエラーになる、といった事故が起きる。
SFT(CHAT 形式)は OpenAI 互換の chat completion 形式で、ルート直下に messages 配列を置く。各メッセージは role(system / user / assistant)と content(文字列、または [{"type": "text", "text": "..."}] 形式の配列。両方を同じファイル内・同じ会話内で混在させてよい)を持つ。system は任意だが、使うなら会話の先頭に置く必要がある。
{"messages": [
{"role": "system", "content": "あなたは親切な旅行アドバイザーです。"},
{"role": "user", "content": "京都で紅葉が見頃になるのはいつ頃ですか?"},
{"role": "assistant", "content": "例年11月中旬から12月上旬が見頃です。"}
]}
weight キーには 2 つの独立した意味がある。メッセージ単位の weight はメッセージオブジェクトの中に置き、値は 0 か 1 のみで、0 ならそのメッセージは損失計算から除外される。一方サンプル単位の weight は JSON オブジェクトのルート直下に置き、任意の浮動小数点数(正・負・0 いずれも可)を取り、そのサンプル全体の損失に掛ける乗数になる。ルート直下の weight を使うなら、データセットの全サンプルにこのキーが存在しなければならない(一部のサンプルだけに付けるのは不可)。値域も置く場所も別物なので、この 2 つを取り違えないことが検証の第一歩になる。
ほかに、assistant メッセージには content の代わりに tool_calls を入れる function calling 用のスキーマ(ルート直下に tools 配列を追加)と、推論トレースを載せる reasoning_content キー(assistant メッセージの中、任意)もある。reasoning_content をどう学習コンテキストへ含めるか(unroll するかどうか)はベースモデル依存で、こみ入った話は第 11 章で扱う。
DPO・ORPO は SFT とは全く別のスキーマで、ルート直下に input(messages 配列と tools を含む)・preferred_output(望ましい応答の配列)・non_preferred_output(望ましくない応答の配列)の 3 フィールドを置く。content は文字列と規定されている(SFT のような content parts 配列は仕様に現れない)。1 例につき単一ターン会話のみに対応し、preferred_output / non_preferred_output は会話の最後の assistant メッセージでなければならない。同じデータセットが DPO・ORPO の両方で使え、どちらの損失関数を使うかはジョブ側の設定(--loss-method)で切り替える。
{
"input": {
"messages": [{"role": "user", "content": "この提案のメリットを教えて"}],
"tools": []
},
"preferred_output": [
{"role": "assistant", "content": "コスト削減と納期短縮の両方が見込めます。"}
],
"non_preferred_output": [
{"role": "assistant", "content": "良いと思います。"}
]
}
RFT(RL 形式)は最もシンプルで、messages 配列だけを持つプロンプトの JSONL である。正解の completion を含める必要はない。SFT・DPO が「良い/望ましい出力の例」を渡すのに対し、RFT は「プロンプト」だけを渡し、別途登録した評価器(reward function)がモデルの出力を 0〜1 でスコアリングして学習を進める。プロンプトさえあれば作れるため、SFT・DPO と比べて用意するデータ量は桁違いに小さく、数十〜数千件、時には 100 件未満でも足りることがある。評価器の作り方や RFT ジョブの起動は第 11 章の範囲になる。
仕組み(2)— 混同しやすい 4 つの上限
データセットには複数の「上限」があり、そのうち混同しやすいのが次の 4 つである。これらはそれぞれ別の軸を制限する独立した制約であり、1 つの数字に単純化できない。混同すると「150MB あれば何でもアップロードできる」「300 万件あれば何エポックでも回せる」といった誤解につながる。
| 制約 | 値(2026-09 時点) | 出典 |
|---|---|---|
| API 単発アップロードのファイルサイズ | 150MB まで | Upload Dataset Files API |
| UI での推奨サイズ | 500MB 未満向き(それ以上は firectl 推奨) | SFT / DPO ガイド共通の記述 |
| データセットの例数 | 最小 3 件・最大 300 万件 | SFT / DPO ガイド共通(Minimum/Maximum examples) |
| 例数 × エポック数 | 300 万以下 | SFT ガイドの Epochs 節 |
エポック(学習データを何周なめるか。1 エポック = 全サンプルを 1 回ずつ学習すること)の数え方が絡むため、特に見落としやすいのが最後の「例数 × エポック数 ≤ 300 万」である。300 万件ちょうどのデータセットを用意できても、既定の 1 エポックしか回せない計算になり、2 エポック回したければ 150 万件以下に抑える必要がある。逆に少量データ(例えば数百件)なら、この上限を気にせず 10 エポック・20 エポックと回すことができる。エポック数は既定 1 で、非整数値(例: 1.5 エポック)も指定できる。
仕組み(3)— アップロードは 3 経路、150MB が分岐点
データセットをプラットフォームへ送る主な手段は、コンソール UI・firectl・REST API の 3 つで、どれを使っても最終的に作られるデータセットリソースは同じである(このほか SDK からもデータセットを作成できる。詳しくは第 14 章で扱う)。
| 経路 | 向くデータ量 | 特徴 |
|---|---|---|
| コンソール UI | 500MB 未満 | dataset タブ → Create Dataset → ウィザードで、作成とアップロードを画面上で完結できる |
firectl dataset create | 大きなファイルにも対応 | 1 コマンドで作成とアップロードの両方を行う(進捗バー付き)。大きなデータセットには firectl が向く、と公式が推奨している |
| REST API | 150MB まで(単発) | 「データセット作成」と「ファイルアップロード」が別リクエストになる。exampleCount はクライアント側が明示的に渡す必要がある |
REST API を単発で使う場合の上限は 150MB である。これを超えるファイルを REST 経由で送るときは、単一の :upload エンドポイントではなく、次の 4 段階のフローに切り替える。
:upload 呼び出しと、署名付き URL を経由する 4 段階のフローに分かれる。- create —
POST /v1/accounts/{account_id}/datasetsにdatasetId(作成するデータセットの ID)とdataset(userUploaded: {}とexampleCountを含む)を渡してエントリだけを先に作る。 - getUploadEndpoint —
POST .../datasets/{dataset_id}:getUploadEndpointに、ファイル名とバイト数のマップ(filenameToSize)を渡す。複数ファイルを一度に扱える。 - 署名付き URL へ PUT — レスポンスに含まれる
filenameToSignedUrls(ファイル名 → 署名付き URL のマップ)を使い、実ファイルをオブジェクトストレージへ直接 PUT する。 - validateUpload —
POST .../datasets/{dataset_id}:validateUploadを呼び、アップロードの完了を確定させる。リクエスト・レスポンスとも空オブジェクトで、これを呼ぶことでデータセットの状態がUPLOADINGからREADYへ遷移すると読める設計になっている。
firectl dataset create なら 1 コマンドで作成とアップロードが済む(公式は大きなデータセットでは firectl を推奨している)。
仕組み(4)— データセットからモデルへ、状態遷移で確認する
データセットのリソースには state というフィールドがあり、実際に目にするのは UPLOADING → READY の 2 つだけである(enum にはこのほか未設定を表す値もある)。学習ジョブを作る前には、必ず READY になっていることを確認する。firectl dataset get <id> -o json を実行すると、state に加えて exampleCount(サンプル数)・estimatedTokenCount(推定トークン数)・averageTurnCount(サンプルあたりの平均ターン数)という、アップロード後にしか分からない統計も確認できる。特に estimatedTokenCount は、学習ジョブのコストや所要時間を見積もる最初の材料になる。
READY になったデータセットは SFT・DPO/ORPO・RFT のいずれのジョブからも参照でき、学習が終わると LoRA モデルにつながる(続きは第 11 章)。もう 1 点、データセットの中身が想定どおりトークナイズされているかを確認する手段として、学習ジョブ作成後にダッシュボードで見られる「Render Samples」機能がある。これはトークン境界と損失マスク(どのトークンが学習対象になっているか)を可視化するもので、データセット側の weight の付け忘れ・付けすぎに気づく最も確実な方法である。実際の使い方は学習ジョブとセットになるため第 11 章で扱うが、「データセットを作って終わりではなく、ジョブを起動したあとに中身の解釈を検証する」という位置づけはこの章のうちに覚えておきたい。
ハンズオン 10-1 小さな SFT 用 JSONL を作って firectl でアップロード・確認・削除する
- ターミナルで API キーを環境変数にセットする(
export FIREWORKS_API_KEY=...)。firectl は第 2 章で発行した API キーで既にサインイン済み(firectl signin。インストールと認証は第 14 章)である前提とする。 - 最小要件(最小 3 件)を満たす、SFT(CHAT 形式)の JSONL ファイルをローカルに作る。ファイル名は
sample-sft.jsonlとする。
{"messages": [{"role": "user", "content": "富士山の標高は?"}, {"role": "assistant", "content": "約3776メートルです。"}]}
{"messages": [{"role": "user", "content": "日本の首都は?"}, {"role": "assistant", "content": "東京です。"}]}
{"messages": [{"role": "user", "content": "1週間は何日?"}, {"role": "assistant", "content": "7日間です。"}]}
データセットの作成・アップロード・削除だけを行うこのハンズオンでは学習ジョブを起動しないため、公式ドキュメントに記載されているトークン課金・GPU 時間課金の対象にはならない。データセットの ID は「1〜63 文字、小文字英数字とハイフンのみ、先頭・末尾にハイフン不可、数字始まり不可」というリソース ID の制約に従う必要があるので、下記のコマンドの ID はそのまま使うか、この制約内で書き換える。
firectlでデータセットを作成・アップロードする(1 コマンドで両方を行う)。
firectl dataset create sample-sft-guide-ch10 ./sample-sft.jsonl \
--display-name "ch10 ハンズオン用サンプル"
- 状態と統計情報を確認する。
stateがREADYになっていれば成功。
firectl dataset get sample-sft-guide-ch10 -o json
exampleCount(3 になっているはず)・estimatedTokenCount・averageTurnCount が出力に含まれていることを確認する。ブラウザでコンソールのデータセット一覧を開き、sample-sft-guide-ch10 を選ぶと、同じデータセットをコンソール上でも確認できる。
- ハンズオンで作ったデータセットを削除する(後片付け)。
firectl dataset delete sample-sft-guide-ch10 --wait
--wait を付けると削除が完了するまでコマンドが待機する。以後 firectl dataset get sample-sft-guide-ch10 を実行すると NOT_FOUND になれば削除完了である。
つまずきポイント
SFT 用データセットを DPO ジョブにそのまま使い回そうとする。 どちらも messages という語を含むが、SFT はルート直下が messages 配列そのもの、DPO/ORPO はルート直下が input(messages を含む)・preferred_output・non_preferred_output の 3 フィールドで、構造が非互換である。学習方法を切り替えるときは、データセットも作り直す前提で考える。
REST API 経由での作成時に exampleCount を渡し忘れる。 firectl や UI ではファイルの中身から自動的に扱われるが、REST の 2 リクエスト方式(作成 → アップロード)では exampleCount をクライアント側が明示的に渡す必要がある、と公式ドキュメントに明記されている。渡し忘れに気づきにくいので、REST を直接叩くコードでは特に注意する。
メッセージ単位の weight とサンプル単位の weight を混同する。 前者はメッセージオブジェクトの中にあり値は 0 か 1 のみ、後者は JSON オブジェクトのルート直下にあり任意の浮動小数点数を取る。後者を使うならデータセットの全サンプルに存在しなければならない。値の意味も置き場所も違うキーが同じ名前を共有している点が、このプラットフォーム最大の紛らわしさの 1 つである。
「150MB」と「500MB」を同じ上限だと思い込む。 150MB は REST の単発アップロード API が扱える上限、500MB はコンソール UI が快適に扱える目安であり、別のレイヤーの別の数字である。500MB 未満だから REST 単発でも安全、とは限らない。150MB を超えるファイルは REST では 4 段階のフローが必要になる(公式は大きなデータセットでは firectl を推奨している)。
理解度チェック
Q1. SFT 用の JSONL ファイルを、そのまま DPO ジョブの学習データとして使えますか?
使えない。SFT はルート直下が messages 配列そのものだが、DPO/ORPO はルート直下が input(messages を含む)・preferred_output・non_preferred_output の 3 フィールドという別スキーマで、構造として互換性が無い。
Q2. 280MB の JSONL ファイルを REST API でアップロードしたい。どうすればよいですか?
単発の :upload エンドポイントは 150MB までしか扱えないため使えない。create → getUploadEndpoint(ファイル名とサイズを渡す)→ 返ってきた署名付き URL へファイルを PUT → validateUpload という 4 段階のフローに切り替える必要がある。
Q3. メッセージ単位の weight とサンプル単位の weight の違いは何ですか?
メッセージ単位の weight はメッセージオブジェクトの中に置き、値は 0 か 1 のみ(0 ならそのメッセージは損失計算から除外)。サンプル単位の weight は JSON オブジェクトのルート直下に置き、任意の浮動小数点数(正・負・0 可)を取り、サンプル全体の損失に掛ける乗数になる。後者を使う場合は全サンプルに必須。
Q4. 300 万件のデータセットを 2 エポック回して学習することはできますか?
できない。「例数 × エポック数」の積に 300 万という上限があるため、300 万件のデータセットを回せるのは 1 エポックまで。2 エポック回したいなら、データセットを 150 万件以下に抑える必要がある。
Q5. RFT 用のデータセットには、SFT のような「正解の応答例」が必要ですか?
必要ない。RFT のデータセットは messages 配列(プロンプト)だけを持つ JSONL で、正解の completion は任意。良し悪しの判定は別途登録する評価器(reward function)が 0〜1 のスコアで行う。
まとめ
- Datasets は SFT・DPO/ORPO・RFT すべての学習ジョブの入口で、コンソール(
app.fireworks.ai/dashboard/datasets)・firectl・REST API のどれでも同じリソースを操作できる - JSONL という共通のファイル形式の中身は、SFT・DPO/ORPO・RFT で互換性のない別スキーマになっている
- 上限は「API 単発 150MB」「UI 500MB 未満向き」「例数 3〜300 万」「例数×エポック 300 万以下」の 4 つが別々に存在し、混同しないこと
- 150MB を超えるファイルは create → getUploadEndpoint → 署名付き URL へ PUT → validateUpload の 4 段階フローで送る
- データセットは実際には
UPLOADING→READYの 2 状態を経て遷移し、READYになって初めて学習ジョブから参照できる
次章では、この章で用意したデータセットを実際に学習ジョブへ渡し、SFT・DPO/ORPO・RFT のどれを選ぶか、どうジョブを起動し、学習済みモデルをどうデプロイするかを見ていく。
参考リンク
- API Reference: Create Dataset
- API Reference: Upload Dataset Files
- API Reference: Get Dataset Upload Endpoint
- API Reference: Validate Dataset Upload
- firectl dataset create
- firectl dataset delete
- Supervised Fine-Tuning - Text
- Preference Optimization with DPO or ORPO
- Reinforcement Fine-Tuning
- Getting Started: Concepts