mcpField
H
huggingface-lora-space-builder

huggingface-lora-space-builder

github.com/huggingfaceクラウド・DevOps11.2k824 回インストール5 日前に更新
リポジトリ

huggingface-lora-space-builder について

ユーザー提供の LoRA で推論する Gradio デモを Hugging Face Spaces に作成・公開するスキルです。モデルカードの確認からパイプライン選定、タスクに合わせた UI 設計、Space の非公開公開までを案内します。

主な機能

  1. 01LoRA ファイルとモデルカードの確認
  2. 02ベースパイプラインと推論手順の選定
  3. 03タスク別 Gradio コントロールの設計
  4. 04app、requirements、README の作成
  5. 05Space の非公開公開

活用シーン

  1. 01Hub 上の LoRA のブラウザデモ作成
  2. 02カスタム UI による拡散モデル LoRA の共有

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/huggingface/skills --skill huggingface-lora-space-builder

インストール後、Claude Code で/huggingface-lora-space-builderを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
adapting-to-the-lora.md
creative-mode.md
tasks.md
zerogpu-and-publishing.md
references/base-models/
krea-2.md
ltx.md
qwen-image.md

詳細

Gradio LoRA Space ビルダー

ユーザー提供の LoRA を使って推論を実行する Gradio デモを Hugging Face Spaces 上で作成し、公開します。LoRA 用の「Space」「デモ」「Gradio アプリ」「プレイグラウンド」の作成、生成、リリース、公開を依頼されたときは、ベースモデルが Qwen-Image、Qwen-Image-Edit、LTX、その他の拡散モデルのいずれであっても使用してください。また、ユーザーがトレーニングした LoRA や Hub でホストしている LoRA について説明し、共有したいと希望しているときも使用してください。デフォルトのターゲットは ZeroGPU ハードウェアで、ベースモデルが対応している場合、デフォルトの推論ライブラリは diffusers です。

出力は、ユーザーがブラウザーで試せる、実際に公開された Space です(デフォルトでは非公開)。ローカルスクリプトではありません。

こうしたデモが優れている理由

デモは、LoRA を汎用テンプレートに付け足したものではなく、その LoRA に合わせて丁寧に作り込まれたものに感じられる必要があります。同じタスクに使われる 2 つの LoRA でも、異なるデモが必要な場合があります。たとえば、ポーズ制御用の動画 LoRA とアウトペインティング用の動画 LoRA は、どちらも動画を入力して動画を出力しますが、ユーザーが提供する入力、前処理、コントロールはまったく異なります。これを見極めることが、この作業の要です。

具体的には、優れたデモには次の特徴があります。

  • 読み込みと実行が速く、モデルの読み込みを最小限に抑え、適切なステップ数を設定し、呼び出しごとの無駄な計算がありません。
  • この LoRA に必要なコントロールだけを備えた UI です。余分なスライダーは機能ではなく、コストです。
  • 進行状況や有用な中間出力、使用したシードを表示し、入力が不足している場合は明確なエラーを示すなど、何が起きているかをユーザーに伝えます。
  • モデルカードに記載された LoRA 独自の推奨事項(トリガーワード、推奨ステップ数、推奨ガイダンススケール、推奨 LoRA スケール、入力例)を守ります。
  • インタラクティブなキャンバス、前後比較スライダー、中間処理の並列プレビューなど、創造性が役立つ箇所では工夫を凝らし、シンプルさが適切な箇所ではシンプルに仕上げます。

ワークフロー

以下のフェーズを順番に進めます。あるフェーズで集めた情報をもとに、次のフェーズを決定します。

  1. パイプラインの選択と UI の設計に必要な LoRA の情報を集めます。
  2. ベースパイプラインと推論レシピを選びます。
  3. この LoRA のタスクと入力に合わせて UI を設計します。
  4. app.py、requirements.txt、README.md をまとめて作成し、3 つすべてを一括承認のためにユーザーに提示します。
  5. Space を公開します(非公開)。

質問を複数のやり取りに分けて少しずつ尋ねないでください。まとめて質問してください。

フェーズ 1 — LoRA の情報を収集する

必須:Hub 上の LoRA リポジトリ(例:username/my-lora)。

まず、トークンなしでリポジトリを読み取れるか試してください。 成功した場合、リポジトリは公開されています。そのまま進めてください。401/403 エラーで失敗した場合、リポジトリは非公開またはアクセス制限付きであり、読み取るには認証済みセッションが必要です。すぐにトークンを求めないでください。 まず、ユーザーがすでに認証済みかどうか確認してください。

from huggingface_hub import HfApi, get_token

cached_token = get_token()  # picks up HF_TOKEN env var or cached CLI login
if cached_token:
    try:
        info = HfApi().whoami(token=cached_token)
        username = info["name"]
        # info also has fine-grained token scope info if applicable
    except Exception:
        cached_token = None  # token exists but is invalid/expired

その後:

  • 有効なキャッシュ済みトークンがあり、かつそれでリポジトリを読み取れる場合は、そのトークンを使用してください。確認は不要です。
  • キャッシュ済みトークンがない場合、またはそのトークンではこの非公開リポジトリを読み取れない場合は、以下の説明を添えて、ユーザーにトークンを一度だけ求めてください。

トークンを求める場合(実際に求める必要がある場合に限ります):

LoRA が非公開またはアクセス制限付きの場合に読み取り、Space を公開するため、write スコープを持つ Hugging Face アクセストークンが必要です。https://huggingface.co/settings/tokens で作成してください。ここに貼り付けてください。

最終フェーズでの公開にも同じトークンを再利用するため、お願いするのは一度だけです。

次に、リポジトリ内の内容を読み取ります:

  • リポジトリのファイル一覧を取得します(huggingface_hub.HfApi().list_repo_files(repo_id))。.safetensors、README.md、サンプル画像・動画、複数のチェックポイントを探してください。
  • モデルカードを取得します(huggingface_hub.ModelCard.load(repo_id))。data dict には構造化されたフィールドがあり、text には README の本文があります。
  • .safetensors ファイルが複数ある場合は、適切なものを選びます。「LoRA の重みファイルの選び方」を references/zerogpu-and-publishing.md で確認してください。概要:README で推奨されているファイルを優先し、次に pytorch_lora_weights.safetensors、その次に最新のトレーニングチェックポイントを選びます。それ以外の場合はユーザーに確認してください。

モデルカードから、以下の情報を特定してください:

  • ベースモデル — base_model フィールド、または README 内の記述を確認します。通常は記載されています。これを使ってパイプラインの参照ファイルを選択します(フェーズ 2 を参照)。
  • タスク — pipeline_tag が設定されていればそれを使用し、設定されていない場合はベースモデルと README の記述から推定します。このスキルが対応するタスクは 5 つです:text-to-image、image-to-image、text-to-video、image-to-video、video-to-video。
  • トリガーワード — 「trigger word」、「instance prompt」、「activation word」などと呼ばれることがよくあります。サンプルプロンプトに含まれている場合もあります。
  • 推奨される推論レシピ — ステップ数、ガイダンススケール、true CFG スケール、LoRA スケール、解像度です。多くの LoRA カードには Python スニペットが含まれています。パラメーター(ステップ数、ガイダンス、CFG、LoRA スケール、dtype)は参考にしてください。読み込み方法については adapting-to-the-lora.md を参照し、スニペットで使われている方法より pipe.load_lora_weights(...) を優先してください。
  • サンプルプロンプトとサンプルメディア — UI の Gradio サンプルとして使用します。
  • サブタスク/具体的な用途 — 画像編集や動画 LoRA では、タスクのカテゴリと同じくらい「この LoRA が実際に何をするのか」が重要です。リライティング LoRA、顔の入れ替え LoRA、スタイル LoRA はすべて image-to-image に分類される可能性がありますが、それぞれ UI は異なります。

推定できない項目がある場合は、ユーザーに一度だけ、まとめて質問してください。 回答しやすい形式で質問してください。タスクのカテゴリについては、5 つの選択肢を番号付きで提示してください。サブタスクについては、1 行で説明を求めてください(「この LoRA は何をしますか? 例:「ポートレートにリライティングを適用する」「マンガ風のスタイルを適用する」「動画をより横長のアスペクト比に拡張する」」)。ベースモデルや README からすでに確実に推定できる場合は、質問しないでください。

モデルカードに役立つ情報がまったくない場合(ベースモデル、タスク、サンプルが何もない場合)は、その旨を明確に伝えてください:「モデルカードには使える情報がありません。次の情報を教えてください:(1)ベースモデル、(2)この LoRA が何をするのか、(3)わかる場合は推奨ステップ数とガイダンススケール。」


フェーズ 2 — ベースパイプラインを選択する

ここで決めることは 2 つあります。読み込むリファレンスファイルと、使用するパイプラインクラスです。これは同じ問題ではありません。ベースモデルファミリーのファイル(例:qwen-image.md)は複数のバリアントを扱い、同じファミリーのバリアントでも、必ずしも同じパイプラインクラスを使うとは限りません。選択を誤ると、Space は起動しても出力が正しくないか、起動時に失敗します。

ステップ 1 — このベースモデルファミリーのリファレンスファイルを読み込みます。

  • references/base-models/qwen-image.md — Qwen-Image および Qwen-Image-Edit ファミリー(テキストから画像生成、画像から画像生成)を扱います。
  • references/base-models/ltx.md — LTX ファミリー(テキストから動画生成、画像から動画生成、動画から動画生成、IC-LoRA を含む)を扱います。
  • references/base-models/krea-2.md — Krea 2(K2)のテキストから画像生成を扱います(RAW でトレーニングし、Turbo 蒸留チェックポイントで推論/LoRA を実行します)。

ベースモデルがこれらのファイルのいずれにも記載されていない場合、このスキルはまだそのモデルを正式にはサポートしていません。そのことをユーザーに伝え、類似モデルにならって進める(最も近いモデルの手順を使って調整する)か、中止するかを確認してください。黙って推測してはいけません。

ステップ 2 — ベースモデル自身のモデルカードでパイプラインクラスを検証します。この手順は必須であり、省略できません。

新しいベースモデルのバリアントは、リポジトリのパスが異なるだけで同じパイプラインクラスを使う場合もあれば、新しいパイプラインクラスを使う場合もあります。リファレンスファイルの表だけを信頼してはいけません。表はベストエフォートで作成されており、最近のリリースへの反映が遅れることがあります。確定する前に検証してください。

from huggingface_hub import ModelCard
base_card = ModelCard.load(base_model_id)
# Read base_card.text — find the diffusers inference snippet, note the pipeline class it imports.

ベースモデルのモデルカードにある diffusers のスニペットでインポートされているクラスが、信頼できる情報源です。重要となる実例を示します。

  • Qwen-Image-Edit は QwenImageEditPipeline を使用します。Qwen-Image-Edit-2509 と Qwen-Image-Edit-2511 は QwenImageEditPlusPipeline を使用します。クラスが異なるだけでなく、デフォルトパラメーターも異なり、1 枚ではなく画像のリストを受け取ります。2511 を対象とする LoRA を QwenImageEditPipeline に読み込むと、出力が壊れます。
  • LTX-Video は LTXPipeline/LTXImageToVideoPipeline/LTXConditionPipeline を使用します。LTX-2 は別のモジュールパスにある LTX2Pipeline を使用します。LTX-2.3 では、diffusers の外部にあるネイティブパイプラインが必要になる場合があります。

ベースモデルのモデルカードに diffusers のスニペットがない場合は、リファレンスファイルの表を使用してください。そのうえで、表にない情報をユーザーが知っている可能性があるため、表を代わりに使用したことを伝えてください。

この検証にかかるコストは、Hub へのフェッチ 1 回と数秒の確認だけです。省略した場合に起こるのは、前述の項目で説明した失敗、つまり、誤ったクラスをひそかに使っている「動作している」Space です。

ステップ 3 — diffusers とネイティブパイプラインを選択します。 ベースモデルに diffusers のパイプラインクラスがある場合は、デフォルトで diffusers を使用します。Qwen-Image、Qwen-Image-Edit、および LTX の大半が該当します。一部の LTX バリアント(特に特定の IC-LoRA を使用する LTX-2.3)では、ネイティブパイプラインが必要です。どの場合に必要かは LTX のリファレンスに記載されています。diffusers では標準の load_lora_weights/set_adapters の動作が得られますが、ネイティブの方法では LoRA 固有の連携処理が必要です。


フェーズ 3 — この LoRA の UI を設計する

テンプレートに頼ってはいけません。LoRA のタスクと入力から、どのような UI が必要かを考えてください。

タスクごとの基本的な UI パターン(T2I、I2I、T2V、I2V、V2V で標準的な入力と出力がどのようなものか)については、references/tasks.md を読んでください。

次に、この特定の LoRA に必要なものを考えるための references/adapting-to-the-lora.md を読んでください。このスキルで最も重要なファイルです。同じタスクでも、必要な UI は大きく異なる場合があります。ポーズ制御 LTX LoRA には、動画入力とポーズ抽出プレビューが必要です。アウトペイント LTX LoRA には、アスペクト比の選択と黒い余白のプレビューが必要です。リライティング Flux LoRA には、画像と、光を追加する場所を指定するブラシキャンバスが必要です。こうしたものを「V2V テンプレート」や「I2I テンプレート」に当てはめることはできません。

UI を書く前にセルフチェックしてください。 ユーザーがこの Space で 10 秒以内に何をするかを、一文で説明してください。その一文で、同じタスクのほかの LoRA と区別できないなら、UI の設計がまだ十分に具体化されていません。

セルフチェックに合格する例:

  • 「動画をアップロードし、目標のアスペクト比を選んで Generate をクリックすると、モデルが空いた余白を埋めます。」
  • 「光を当てたい場所に色付きのブラシストロークを描き、照明スタイルを選んで Generate をクリックすると、モデルが写真をリライティングします。」
  • 「動いている人物の動画と別のキャラクターの画像をアップロードすると、モデルがその動きをするキャラクターの動画を生成します。」

不合格の例:

  • 「プロンプトを入力して Generate をクリックします。」(一般的な T2I です。もっと具体的にしてください。)
  • 「画像と指示をアップロードします。」(一般的な編集です。どのような編集でしょうか?)

Gradio コンポーネントの最新状況。 Gradio のコンポーネントは進化しています。標準的なコンポーネントを使うと決める前に、より新しいものが適していないか検討してください。たとえば、編集 LoRA のビフォーアフター表示には gr.ImageSlider、設定の永続化には gr.BrowserState、入力に応じて変わる UI には @gr.render が使えます。コンポーネントが存在するか、どのようなシグネチャを持つか不明な場合は、推測せず https://www.gradio.app/docs から最新の Gradio ドキュメントを取得してください。

標準コンポーネントと Hub のカスタムコンポーネントでは不十分な場合 — クリエイティブモード。 LoRA の自然な入力が、Gradio のコンポーネント(組み込みまたは Hub 上のもの)ではうまく表現できない形状の場合(点の集合、ストローク、軌跡、メタデータ付きの複数領域の注釈、3D 回転ギズモ、タイムラインスクラバーなど、メディア上でユーザーが何かを操作するもの)、gr.HTML を使ったカスタム HTML/JS に切り替えてください。gr.HTML、head= による注入、elem_id による指定、2 種類の JS↔Python 状態同期方式といった Gradio のプリミティブ、JSON ワイヤーフォーマットの定義に関する原則、および注意点については references/creative-mode.md を参照してください。面白そうだからという理由だけでクリエイティブモードを使うのではなく、LoRA の入力形状が必要とする場合に使ってください。また、完全な独自実装に進む前に、上記の Hub カスタムコンポーネントの段階を飛ばさないでください(例:gradio_image_annotation)。

メディア入力を扱う Space での gr.Examples。 モデル自体のリポジトリに適切なサンプルメディアがない場合は、モダリティごとに分割され、HF データセットビューアーで適切なサムネイルを表示できる共有入力プールから取得してください。画像は linoyts/repo-to-space-example-inputs、動画は linoyts/repo-to-space-example-videos です。どちらも CC0 で、categories と自然言語の caption のメタデータ、および各データセットの README に記載された同じフィルター/ランク付けの手順が含まれています。タスクに合うものを 2~3 個選び、モデルが期待する形状に前処理して、Space にコピーを組み込んでください。ビルド時にサンプルを実行せず、最初のクリック時にキャッシュされるよう、cache_examples=True, cache_mode="lazy" を設定してください(references/zerogpu-and-publishing.md を参照)。

フェーズ 4 — Space のファイルを作成する

書き始める前に、これから行う作業を具体的にユーザーに伝え、実際のファイル名を挙げてください。「3 つのファイルを書きます」ではなく、次のようにします。

「これから Space の公開に必要な 3 つのファイルを作成します。app.py(Gradio のデモと推論コード)、requirements.txt(Python の依存関係)、README.md(ZeroGPU のハードウェア設定を含む Space の設定)です。その後、公開前に確認していただけるよう、3 つすべてをまとめてお見せします。」

これにより、何を作成するのかがユーザーに明確に伝わります。ファイル名を挙げずに「3 つのファイル」とだけ言うのは曖昧で、成果物に対する確約が不足している印象を与えます。

3 つのファイルは密接に連携しています。requirements.txt は app.py のインポート内容で決まり、README.md の YAML フロントマターでは SDK のバージョン、ハードウェア、Space のタイトルを設定し、それらを一致させる必要があります。3 つをまとめて作成し、公開前にユーザーの承認を得るため、1 回のメッセージでまとめて提示してください。

ZeroGPU のルールについては references/zerogpu-and-publishing.md を読んでください。特に分かりにくい点は次のとおりです。

  • モデルはモジュールレベルで cuda に配置してください(GPU 関数内で遅延読み込みしないでください)。ZeroGPU は割り当て前でも動作する CUDA エミュレーションを備えており、モジュールレベルで配置するほうが遅延配置より大幅に高速です。
  • 推論を実行する関数には @spaces.GPU(duration=...) デコレーターを付けてください。タスクに適した時間を選びます。画像生成では短め、動画では長めに設定してください。
  • torch.compile は使用しないでください。ZeroGPU のプロセスモデルと互換性がありません。
app.py

フェーズ 1〜3 で決めた要素を組み合わせてください。テンプレートをそのまま貼り付けないでください。各セクションは必要な理由がある場合にのみ含めます。

  • インポート — gradio as gr、torch、spaces、パイプラインクラス、前処理に必要なもの。
  • 定数 — LORA_REPO、BASE_MODEL、推奨ステップ数、ガイダンス、LoRA スケール、トリガーワード。
  • モデルのモジュールレベルでの読み込み — パイプラインの from_pretrained、.to("cuda")、load_lora_weights。LoRA リポジトリが非公開の場合は、token=os.environ["HF_TOKEN"] を渡してください。
  • 前処理関数(必要な場合) — ポーズの抽出、パディング、マスクの作成など。CPU コードはモジュールレベルで実行できます。GPU コードは @spaces.GPU 関数の中に記述する必要があります。
  • 推論関数 — @spaces.GPU(duration=...) デコレーターを付けます。入力を検証し、トリガーワードを適用し、パイプラインのキーワード引数を構築して、出力を返します。
  • Gradio Blocks — フェーズ 3 の UI を作成し、推論関数に接続します。

正しく実装するための一般的な注意事項:

  • 結果と一緒に実際に使用したシードを返し、ユーザーが再現できるようにします。
  • 推論関数に gr.Progress(track_tqdm=True) を指定すると、diffusers 内部の進捗バーが表示されます。
  • 入力を検証します。必須入力がない場合は、パイプラインで分かりにくいエラーが発生するのを避け、gr.Error("Please upload an image first.") を送出します。
  • gr.Examples では cache_examples=True, cache_mode="lazy" を使用します。cache_examples=True だけを指定すると、ビルド時に例を実行するため、ZeroGPU で失敗します。遅延モードでは、最初にユーザーがクリックしたときにキャッシュが作成されます。
  • gr.Examples に fn= がある場合、行をクリックすると inputs= の値のみが位置引数として fn に渡されます。そのため、inputs にない fn の各パラメーターにはデフォルト値が必要です。そうでないと、クリック時に TypeError: missing N required positional arguments が発生します。実行イベントではすべてのコンポーネントが接続されるため、手動テストやスモークテストには合格しても、例のクリック時だけ失敗します。対処方法:追加パラメーターにデフォルト値を設定する(inputs=[prompt] はそのままにする)、すべての入力を全行の例とともに列挙する、または fn/outputs を削除して、クリック時にはフィールドに値を入力するだけにします。
requirements.txt

固定された最小限のリストを用意して、うまくいくことを期待してはいけません。「最小限」のリストは通常の T2I LoRA では機能しますが、ベースモデルに視覚言語テキストエンコーダー、動画出力、または単純ではない前処理が含まれていると、すぐに問題が起きます。requirements.txt は Space が実際に必要とするものから導き出してください。順序は次のとおりです。

  1. app.py にある、標準ライブラリ以外のトップレベルのインポートすべて。 app.py に import cv2 があれば、requirements.txt に opencv-python を記載します。from controlnet_aux import OpenposeDetector があれば、requirements.txt に controlnet-aux を記載します。インポートを機械的に確認してください。(一部のインポートは実行環境に組み込まれており、記載する必要がありません。次の段落にある除外項目に注意してください。)
  2. ベースモデルの参照にある「Required dependencies」セクションの内容。 各ベースモデルのファイルには、パイプラインが必要とする、見落としやすい追加依存関係が記載されています。たとえば、Qwen-Image(Qwen 2.5-VL テキストエンコーダー)には torchvision、LTX(動画のエクスポート)には imageio[ffmpeg] が必要です。すべて含めてください。これらの依存関係は、パイプラインのコンポーネントが読み込み時に推移的にインポートするため、インポートの確認だけでは見つかりません。
  3. LoRA のモデルカードに、インストールが明記されている依存関係。 LoRA の README に pip install ブロックがあれば、そこから依存関係を記載してください。
  4. diffusers/Transformers 関連のスタック: diffusers、transformers、accelerate、peft、safetensors。デフォルトではバージョンを指定しません。ベースモデルの参照でモデルが必要としていることが示されている場合は、diffusers を git+https://github.com/huggingface/diffusers に変更します(最近のリリースで必要となることがよくあります。現在の例として Qwen-Image-Edit-2511 があります)。

requirements.txt に記載しないもの:

  • gradio — requirements.txt ではなく、README.md の YAML フロントマターにある sdk_version: フィールドで管理します。requirements に記載しても、無視されるか、SDK とのバージョン競合を起こします。バージョンは README のみに設定してください。
  • torch — Space のランタイムによって提供されます。特定のバージョンを固定する必要がある場合にのみ追加してください(まれなケースであり、通常はほかに問題があることを示します)。
  • spaces — Space のランタイムによって提供されます。特定のバージョンを固定する必要がある場合にのみ追加してください。
  • huggingface_hub — Space のランタイムによって提供されます。特定のバージョンを固定する必要がある場合にのみ追加してください。

これら4つは ZeroGPU コンテナにあらかじめインストールされています。それでも記載するのは、「省くより含める」という考え方が、ベースライン以外の依存関係には適切でも、ベースラインの依存関係には不適切であることを示す典型例です。ランタイムが管理するバージョンとの競合を招くためです。

それ以外のものは、迷ったら含めてください。 Space が実際には使わないパッケージがあっても、ビルドが少し遅くなるだけです。必要なパッケージが欠けていると、起動時にクラッシュし、ユーザーが原因を特定するのがはるかに難しくなります。この2つのコストは同等ではありません。このルールのきっかけとなったテスト失敗は、まさに後者でした。

ただし、ZeroGPU では追加すると解決する問題よりも、かえって問題を起こすことが多いため、反射的に追加してはいけない依存関係が2つあります。

  • xformers — 特定の torch バージョンに固定されており、競合の原因になることがよくあります。ZeroGPU ランタイムには torch 2.8 以降が含まれているため、固定する xformers のバージョンはそれに対応している必要があります。Blackwell では、さらに注意が必要です。xformers の FA3 ディスパッチはハードウェアの判定を誤ります(FA3 カーネルは sm_90a の Hopper 専用ですが、ディスパッチャーの判定は device_capability >= (9, 0) で、Blackwell も該当します)。その結果、カーネル起動時に CUDA invalid argument でクラッシュします。xformers のアテンションを使う Space でこれが発生した場合は、モジュールの読み込み時に FA3 ディスパッチを無効にしてください。

    try:
        from xformers.ops.fmha import _set_use_fa3
        _set_use_fa3(False)
    except Exception:
        pass
    

    app.py で実際に使用している場合にのみ、xformers を含めてください。

  • flash-attn — ビルド手順が必要で、インストールに失敗することもよくあります。xformers と同様、torch 2.8 以降との互換性に注意してください。app.py で実際に使用している場合にのみ含めてください。

ほかのバージョンは、理由がある場合にのみ固定してください(既知の互換性問題や、モデルカードの手順に合わせる場合など)。

README.md

Space は README.md の先頭にある YAML フロントマターで設定します。このフロントマターによって ZeroGPU が選択されます。

---
title: <human-readable title>
emoji: 🎨
colorFrom: pink
colorTo: purple
sdk: gradio
sdk_version: <current Gradio version>
app_file: app.py
pinned: false
hardware: zero-a10g
short_description: <one short line for the Space tile, ~60 chars max>
models:
  - <base model repo>
  - <lora repo>
---

# <title>

A short description with links to the LoRA and base model.

主なフィールド:

  • sdk: gradio — ZeroGPU に必須です。
  • sdk_version — 使用した Gradio のバージョンに合わせます。推測せず、現在のバージョンを調べてください(pip index versions gradio を実行するか、https://www.gradio.app を確認してください)。
  • hardware: zero-a10g — ZeroGPU の旧来の識別文字列です。実際のハードウェアは NVIDIA RTX Pro 6000 Blackwell ですが、識別子は zero-a10g です。ZeroGPU は PRO、Team、Enterprise アカウントで利用できます。ユーザーがサブスクリプションに加入していない場合、Space は CPU にフォールバックします。PRO を利用していないと思われる場合は、その旨を伝えてください。
  • models: — ベースモデルと LoRA のリポジトリを一覧にします。これにより、Hub のキャッシュと検索が有効になります。
  • short_description — Space のタイルに表示されます。短く(約60文字以内に)してください。 Hub の YAML バリデーターは長い値を https://huggingface.co/api/validate-yaml からの 400 エラーで拒否します。このエラーは create_repo または upload_file の実行中に HfHubHTTPError として現れます。サーバー側の正確な上限は公開されておらず、変更される可能性もあるため、上限ぎりぎりを狙わず、タイル上で表示できる長さを目安にしてください。400 エラーが発生した場合は、ほとんどの場合、このフィールドを短くすれば解決します。Space の内容を説明する一文で十分です。長い説明は YAML の下にある README 本文に記載してください。
まとめて一度に承認を得る — 作業順序が重要です

ここでの基本方針は、まず3つのファイルをすべて作成し、その後、1つのメッセージですべてまとめて提示することです。「app.py を書く → それについて話す → requirements を書く → それについて話す → README を書く → それについて話す」という流れではありません。この進め方では、明示的に承認を求めなくても、各ファイルの後にユーザーの反応を促すことになり、3回の承認機会が生じます。

具体的には、次のとおりです。

  1. 間に文章を挟まず、app.py、requirements.txt、README.md を続けて作成します。 ファイルの間に解説を入れません。「次のファイルを書きます」とも言いません。各ファイルの役割を、作成しながら説明することも避けます。3つのファイルを続けて提示するだけです。
  2. その後、1つのメッセージですべてをまとめて承認するよう求めます。 たとえば、「こちらが Space です。app.py(N 行)、requirements.txt、README.md を確認し、公開を承認するか、変更点をお知らせください。」のようにします。
  3. ユーザーは一度だけ返答し、3つのファイルのいずれに対する変更希望もまとめて伝えます。

避けるべきこと:

  • app.py を書いた後、ほかのファイルを書く前に、その構成や設計上の選択について説明すること。説明は、事前の作成開始時の案内(Phase 4 の冒頭)か、3つのファイルをすべて作成した後の承認依頼メッセージにまとめます。
  • 「次に進んでもよいですか?」や「次は requirements を作成しましょうか?」と尋ねること。これらはファイルごとの暗黙の承認依頼です。
  • ファイルを1つだけインラインで提示し、「準備ができたら次のファイルを見せます」と申し出ること。これも同じ問題につながります。
  • 3つのファイルのうち、どれかを任意のものや後続の作業として扱うこと。3つは1つの成果物としてまとめて作成します。

最初のファイルを見た後、ユーザーが質問やフィードバックを伝えるために作業を中断しても問題ありません。その場合は対応してください。ただし、その後にコードを作成するときは、残りのファイルを1つずつではなく、すべてまとめて作成するというルールは変わりません。


フェーズ 5 — Space を公開する

フェーズ 1 で認証したセッションを使用します。まずは 非公開 にして、ユーザーが内容を確認してから公開に切り替えられるようにします。作成前にユーザーに対象のユーザー名を確認します:「{username}/{space_name} に公開します。よろしいですか?」

from huggingface_hub import HfApi, SpaceHardware

api = HfApi(token=hf_token)
username = api.whoami()["name"]
repo_id = f"{username}/{space_name}"

api.create_repo(
    repo_id=repo_id,
    repo_type="space",
    space_sdk="gradio",
    space_hardware=SpaceHardware.ZERO_A10G,
    private=True,
    exist_ok=True,
)

# Upload files
for path in ["app.py", "requirements.txt", "README.md"]:
    api.upload_file(path_or_fileobj=path, path_in_repo=path,
                    repo_id=repo_id, repo_type="space")

LoRA リポジトリ自体が非公開またはアクセス制限付きの場合、Space が実行時に LoRA をダウンロードするためにトークンが必要です。Space シークレットとして設定します。

api.add_space_secret(repo_id=repo_id, key="HF_TOKEN", value=HF_TOKEN)

…また、app.py では token=os.environ["HF_TOKEN"] を指定して LoRA を読み込みます。

アップロード後、共有する前に以下のスモークテストを実行します。ビルドは非同期で実行され、weight_name の誤り、依存関係の不足、パイプラインクラスの誤りといったサイレントな失敗は、最初の推論時に初めて表面化します。スモークテストに合格したら、Space の URL(https://huggingface.co/spaces/{repo_id})を共有し、Space は非公開であるため、閲覧にはログインが必要だとユーザーに伝えます。ビルドには数分かかります。失敗した場合、ログは https://huggingface.co/spaces/{repo_id}/logs/container で確認できます。

公開時の失敗(ビルド開始前):

  • create_repo または upload_file の実行中に https://huggingface.co/api/validate-yaml から HfHubHTTPError: 400 Bad Request が返される。README の YAML がサーバー側の検証に失敗しています。圧倒的に多い原因は short_description が長すぎることです。まれに、不要なフィールドや不正な値が原因の場合もあります。対処法:short_description を約 60 文字に短くして、再試行します。短くしても解決しない場合は、フィールド名の誤字や無効な値(例:colorFrom/colorTo の未対応の色、無効な hardware 文字列)がないか確認します。
  • space_hardware="zero-a10g" を指定した create_repo で 403 が返される:ユーザーが PRO/Team/Enterprise を利用していないため、作成時に ZeroGPU をリクエストできません。対処法:space_hardware を指定せずに create_repo を再試行し、README の YAML では hardware: zero-a10g をそのままにします。Space は CPU で作成されます。その後、ユーザーは PRO にアップグレードする(ZeroGPU に自動で移行)か、コミュニティ GPU 助成 に申請できます(Space のハードウェア設定からリクエストします)。
  • upload_file で 401/403 が返される:トークンに書き込みスコープがありません。対処法:書き込みスコープ付きのトークンをユーザーに求めます。

よくあるビルド失敗(ビルド開始後):

  • load_lora_weights での LoRA の weight_name の不一致 → list_repo_files を使って実際のファイル名を確認します。
  • ベースモデルにアクセス制限があり、トークンが Space シークレットに設定されていない。
  • ZeroGPU が割り当てられていない(ユーザーが PRO を利用していない)→ Space は CPU にフォールバックし、実用に耐えないほど遅くなります。
  • Diffusers のバージョンがパイプラインクラスを認識しない → requirements.txt で git diffusers を固定します。
  • モジュール読み込み時に依存関係が不足している → 上記の requirements.txt の導出ルールを参照してください。最もよくあるのは、Qwen-Image のテキストエンコーダーに必要な torchvision などの間接依存関係です。

ビルドに失敗した場合は、ログを確認して修正案を提案すると申し出ます。


フェーズ 6 — Space のスモークテスト

Space を完成と宣言してユーザーに URL を渡す前に、最初から最後まで一度動作させてください。weight_name の誤り、パイプラインクラスの誤り、間接依存関係の不足、ゲート付きベースモデルのトークンに関する問題など、いくつかの障害はビルドに成功しても、最初の推論で初めて表面化します。Python パッケージの gradio には、まさにこの確認を行う CLI が含まれています。gradio info はエンドポイントのシグネチャを返し、gradio predict は実際の推論を実行します。どちらも Space に必要な gradio pip 依存関係に含まれているため、このスキルを実行した環境ならどこでも利用できます。

ステップ 1 — ビルドの完了を待ちます。 create_repo はすぐに戻りますが、コンテナイメージはまだビルド中です。HfApi().get_space_runtime(repo_id).stage をポーリングし、RUNNING に達するまで待ちます。

import time
from huggingface_hub import HfApi
api = HfApi(token=hf_token)
while True:
    stage = api.get_space_runtime(repo_id).stage
    if stage == "RUNNING": break
    if stage in {"BUILD_ERROR", "RUNTIME_ERROR", "CONFIG_ERROR"}:
        raise RuntimeError(f"Build failed: {stage}. Logs: https://huggingface.co/spaces/{repo_id}/logs/container")
    time.sleep(15)

ビルドに失敗した場合は、コンテナログ(https://huggingface.co/spaces/{repo_id}/logs/container)を取得し、トレースバックを確認して、修正案を提案してください。実行中でない Space に対して gradio info を実行しないでください。ハングするか、503 エラーになります。

ステップ 2 — エンドポイントのシグネチャを確認します。 gradio info {repo_id} --token {hf_token} は、公開されているエンドポイントとそのパラメーターの型を返します。出力を確認し、次の点を検証してください。(a)エンドポイントが存在する(デフォルトは /predict ですが、Blocks の Space では Python 関数名に由来するカスタム名が付いていることがよくあります)、(b)パラメーターの順序が app.py の宣言と一致している、(c)ファイル型パラメーターに想定どおり "type": "filepath" と表示されている。これらが一致していなくても、ユーザー向け UI は正しく表示される場合がありますが、API 呼び出しは失敗します。修正して再アップロードしてください。

ステップ 3 — 実際の推論を 1 回実行します。 実行可能な入力のうち最も軽いものを選びます。LoRA カードの最もシンプルな例、または gr.Examples のエントリーを使用してください。プライベートな Space には --token を渡します。ファイル入力の場合、ペイロードには {"path": "...", "meta": {"_type": "gradio.FileData"}} を使用します。

# Text-to-image:
gradio predict {repo_id} /predict '{"prompt": "...", "aspect_ratio": "1:1", ...}' --token $HF_TOKEN

# Image-to-image (file input):
gradio predict {repo_id} /predict '{"input_image": {"path": "/tmp/sample.jpg", "meta": {"_type": "gradio.FileData"}}, "prompt": "..."}' --token $HF_TOKEN

I2I 用のローカルサンプル画像がない場合は、LoRA リポジトリ(hf_hub_download(repo_id, filename="example.png"))またはベースモデルのカードから取得してください。

クリエイティブモードの Space に関する注意点。 gradio info と gradio predict で確認できるのは Python エンドポイントのみです。gr.HTML ウィジェット内のカスタム JS が動作するかどうかは確認できません。Space がクリエイティブモードを使用している場合(references/creative-mode.md を参照)、API のスモークテストに合格した後、共有する前にブラウザーで Space の URL を開き、インタラクションを一度確認してください。サーバー側は問題ないのに JS が壊れているのが、これらで最もよくある障害です。

ステップ 4 — 結果を判断します。

  • 正常に返り、出力も妥当に見える → 完了です。URL を共有してください。
  • HTTPError 503 / "Space is sleeping" → ステップ 1 と 3 の間に Space がスリープ状態になりました。起動し(api.restart_space(repo_id))、再試行してください。
  • weight_name / safetensors に関する推論エラー → app.py の LoRA ファイル名が LoRA リポジトリ内の実際のファイル名と一致していません。list_repo_files を再確認し、weight_name= を修正して、app.py を再アップロードしてください。
  • パイプラインクラスまたは属性の不足に関する推論エラー → diffusers のバージョンが古すぎます。requirements.txt を git+https://github.com/huggingface/diffusers に切り替えて再アップロードしてください。
  • モジュール読み込み時の ImportError → 依存関係が不足しています。requirements.txt に追加して再アップロードしてください。実行時ログ(/logs/run)に不足しているパッケージが記載されています。
  • OOM → デフォルトの解像度またはステップ数を下げるか、より小さいベースバリアントを選んでください。
  • タイムアウト / ハング → @spaces.GPU(duration=...) の値を増やして再アップロードしてください。

スモークテストの目的は、「ユーザーが問題を見つけて報告してくる」状況から、「共有する前に自分で問題を見つけて修正する」状況に変えることです。ビルドに成功したからといって省略しないでください。ビルドは成功しても推論は失敗する、というのが、複雑なパイプラインを使う Space で最もよくある障害です。


避けるべきこと

  • 「すべての LoRA 向けの汎用デモ」というテンプレートです。このスキルの要点は、それぞれに合わせて調整することです。
  • GPU 関数内でモデルを遅延ロードすることです。ZeroGPU では時間がかかり、最初のリクエストまで起動時のエラーが隠れてしまいます。
  • torch.compile です。ZeroGPU ではサポートされていません。
  • ZeroGPU で cache_mode="lazy" を指定せずに cache_examples=True を使うことです。
  • 推論関数で必須の引数を網羅していない inputs を指定した gr.Examples(fn=…) です。ビルドは成功しても、最初にサンプルをクリックすると必須の位置引数がないというエラーでクラッシュします。
  • LoRA の重みを Space リポジトリにアップロードすることです。実行時に LoRA 自身の Hub リポジトリから取得してください。
  • 最後になってから HF トークンを求め、その LoRA が最初から非公開だったためモデルカードを読み取れなかったと気づくことです。
  • diffusers のすべての設定項目を公開することです。この LoRA にとって重要な 1〜3 個の設定だけを選んでください。
  • Space の公開後、チャットの返信に長い前置きを入れることです。納品物は Space の URL です。完了報告は簡潔にしてください。

コメント