概要
JSONは、構造化データをテキストとして記述する最も一般的な方法です。オブジェクトは波括弧、リストは角括弧で囲み、キーと値は引用符で囲みます。JSON Linesまたは改行区切りJSONとも呼ばれるJSONLは、これに1つのルールを追加します。それは、ファイルの各行が完全で有効な1つのJSON値であり、行が改行で区切られていることです。トレーニングデータの場合、各値は1つのサンプルを保持するオブジェクトになります。
{"messages":[{"role":"system","content":"You are…"},{"role":"user","content":"How do I reset my password?"},{"role":"assistant","content":"Open Settings → Security…"}]}{"messages":[{"role":"user","content":"Hi"},{"role":"assistant","content":"Hello! How can I help?","weight":0},{"role":"user","content":"Export my report as PDF"},{"role":"assistant","content":"Open the report, click Export → PDF…","weight":1}]}{"messages":[{"role":"system","content":"You are…"},{"role":"user","content":"Can I change my plan mid-month?"},{"role":"assistant","content":"Yes. The difference is prorated…"}]}1レコードにつき1行、行間のカンマなし、全体を囲む [ ] なし{ … }1つの完全なJSONオブジェクト = 1つの学習レコード"messages"会話(順序通り)"role"発言者:system、user、またはassistant"weight"この応答を学習する(1)、または読み込むのみ(0)\n改行でレコードが終了トレーニングでこれを使用する理由
- ストリーミング: プロバイダーは数ギガバイトのファイルを全体として読み込んで解析するのではなく、1行ずつ読み取ることができます。
- 独立性: ファイルの残りの部分を解析することなく、レコードのカウント、シャッフル、トレーニング用と検証用への分割、またはサンプリングを行うことができます。
- 明確なエラー: 不正な形式のレコードは1行のみを破損させ、エラーメッセージでその箇所を特定できます(例:「line 482: unexpected end of input」)。
- 追記可能: サンプルを追加する場合は行を追加するだけであり、ファイル内の他の部分は変更されません。
ルールとファイルが破損する原因
JSON Linesの仕様には3つのルールがあります。ファイルがUTF-8であること、各行が有効なJSON値であること、そして各行が改行文字で終わることです。ファイルの末尾を改行で終わらせることが強く推奨されています。破損したトレーニングファイルのほぼすべてが、以下のいずれかのルールに違反しています。
✗ {"messages": [ ... ← a pretty-printed object split over lines
{"role": "user", ... } ]}
✗ [ {"messages": ...}, {"messages": ...} ] ← a JSON array, not one object per line
✗ {"messages": [...]}, ← trailing comma
✗ ← a blank line in the middle
✓ {"messages":[...]} ← one complete object, then a line breakメッセージのテキスト内の改行は問題ありません。JSONでは文字列内にエスケープされて(バックスラッシュの後にnが続く形で)保存されるためです。許可されないのは、オブジェクトの途中に実際の改行が含まれることです。これはまさに、可読性のためにファイルを「整形(プリティプリント)」したときに起こる現象です。
同じフォーマット、異なる形式
主要なファインチューニングサービスはすべてJSONLに対応していますが、行内に記述するスキーマはそれぞれ独自に定義しています。system、user、assistantのロールを持つmessagesリストを使用するものもあれば、システムプロンプトを別のフィールドに配置するものもあります。また、リストをcontents、アシスタントのロールをmodelと呼ぶものや、各アシスタントメッセージにweightをサポートし、以前の返答をコンテキストとしてのみ扱うようにするものもあります。
// chat "messages" (with an optional weight per assistant reply)
{"messages":[{"role":"user","content":"Hi"},{"role":"assistant","content":"Hello!","weight":0},{"role":"user","content":"Export as PDF"},{"role":"assistant","content":"Open the report, click Export → PDF.","weight":1}]}
// "contents" with user / model roles
{"contents":[{"role":"user","parts":[{"text":"Export as PDF"}]},{"role":"model","parts":[{"text":"Open the report, click Export → PDF."}]}]}
// separate system field
{"system":"You are a support assistant.","messages":[{"role":"user","content":"Export as PDF"},{"role":"assistant","content":"Open the report, click Export → PDF."}]}メッセージごとの重み付けがないフォーマットの場合、複数のターゲットを持つマルチターン会話は、ターゲットごとに1つのレコードとして記述され、それぞれターゲットの返答の直後で切り捨てられます。これらのレコードでは、以前のアシスタントの返答をコンテキストとしてのみマークする方法がないため、それらも学習の対象となります。
- 会話には4つのメッセージが含まれます。「こんにちは」、挨拶、「レポートをPDFとしてエクスポートして」、そして指示です。指示のみがターゲットとしてマークされています。
- 重みをサポートするプロバイダーの場合:1行で、挨拶を
weight: 0、指示をweight: 1とします。 - 重みをサポートしないプロバイダーの場合:同じく1行で、指示で終わります。挨拶もターゲットであった場合、挨拶で終わる行と指示で終わる行の2行になり、挨拶は2回学習されることになります。
- どちらのファイルにも、同じようにクリーニングおよび墨塗りされたテキストが含まれています。異なるのはラッピングのみです。
よくある間違い
- トレーニングファイルを整形(プリティプリント)して、各オブジェクトを複数行にまたがらせること。
- レコードのJSON配列を保存し、拡張子を.jsonlと命名すること。
- エンコーディングを変更したりスマートクォートを追加したりするツールでファイルを手動編集し、JSONを破損させること。
- あるプロバイダーのファイルを別のプロバイダーで再利用すること。フォーマットは同じでも、内部のスキーマが異なります。
参考文献および関連資料
外部ソースは新しいタブで開きます。
- 01JSON Linesjsonlines.org · jsonlines.org短い仕様:UTF-8、1行に1つの値、値の間に改行。
- 02RFC 8259: The JavaScript Object Notation (JSON) Data Interchange FormatIETF · RFC Editor · rfc-editor.org文字列が改行をエスケープする方法を含む、JSON標準そのもの。
- 03Supervised fine-tuningOpenAI API docs · developers.openai.comチャットの`messages`の構造。
- 04Prepare supervised fine-tuning data for Gemini modelsGoogle Cloud documentation · docs.cloud.google.comユーザーとモデルのロールを持つ`contents`の構造。
- 05Prepare data for fine-tuning your modelsAmazon Bedrock User Guide · docs.aws.amazon.com独立したシステムフィールドを持つ構造と、モデルごとの制限。