sd.keydrop.net

sd.keydrop.net ユーザーマニュアル

sd.keydrop.net は、ブラウザ内の WebGPU で AI 画像生成を行う完全ローカルのツールです。Stable Diffusion 互換モデルに対応しています。 サーバーにデータを送信しない設計のため、プロンプト・モデル・生成画像のプライバシーが保たれます。

本マニュアルでは、モデルの入手から画像生成、LoRA マージ、設定変更、トラブルシューティングまでを解説します。

動作環境

sd.keydrop.net はブラウザ内の WebGPU で AI 推論を行うため、一般的な Web アプリよりも高いスペックが必要です。 使用するモデルの種類によって要求が大きく変わります。

Mac

項目 最小スペック 推奨スペック
チップ Apple M1 Apple M2 Pro / M3 Pro 以上
メモリ (RAM) 8GB(SD-Turbo のみ) 32GB 以上
GPU メモリ 統合メモリ(RAM と共有)
ストレージ 5GB 空き 30GB 以上の空き
OS macOS 13+ macOS 14+
ブラウザ Chrome 121+ / Arc / Edge(Safari 非対応)

Windows

項目 最小スペック 推奨スペック
GPU NVIDIA GTX 1060 (VRAM 6GB) NVIDIA RTX 3060 Ti (VRAM 8GB) 以上
メモリ (RAM) 8GB 32GB 以上
VRAM 4GB(SD-Turbo のみ) 8GB 以上
ストレージ 5GB 空き 30GB 以上の空き
OS Windows 10 Windows 11
ブラウザ Chrome 121+ / Edge 121+ / Arc

モデル別のスペック要求

ブラウザはモデルファイル全体をメモリに読み込むため、モデルのファイルサイズ ≒ 必要な RAM と考えてください。 外部データファイル(.onnx.data)がある場合はそのサイズも加算されます。

モデル ファイル合計 必要 RAM 必要 VRAM 解像度
SD-Turbo (fp16) ~2GB 8GB 4GB 512×512
SD 1.5 (weight-only fp16) ~2GB 8GB 4GB 512×512
SDXL (fp32) ❌ ~13GB 32GB 以上 8GB 1024×1024 (現時点では動作不可)
(軽量版 Segmind Vega は ~1.4GB で動作の可能性あり)
最小スペックの制約:RAM 8GB / VRAM 4GB の環境では、SD-Turbo(fp16, ~2GB)のみが実用的です。 SD 1.5 や SDXL モデルを使いたい場合は、推奨スペック(RAM 32GB / VRAM 8GB)以上の環境が必要です。 特に SDXL は UNet だけで 9.6GB あるため、メモリに余裕がないとブラウザがクラッシュする場合があります。
Mac ユーザーへ:Apple Silicon Mac は GPU メモリと RAM が共有(統合メモリ)です。 SDXL を動かすには、モデルファイル読込 + WebGPU 推論バッファの両方が RAM から割り当てられるため、36GB 以上の統合メモリが理想的です。 M1 / M2(8GB / 16GB)では SD-Turbo 以外は実用困難です。
⚠️ SDXL モデルの制約(2026年4月時点)

SDXL の UNet は fp16 でも約 4.8GB あり、ブラウザの 1 タブに割り当てられるメモリ上限(通常 4〜8GB)を超えるため、現時点では動作しません。 これは PC の RAM やスペックに関係なく、ブラウザ(Chrome / Edge / Arc)のアーキテクチャ上の制限です。

sd.keydrop.net では SD-Turbo および SD 1.5 系モデルを推奨します。 将来ブラウザのメモリ制限が緩和されるか、SDXL の軽量化モデルが登場した場合に対応を再検討します。

対応ブラウザ

ブラウザ WebGPU 対応状況
Chrome 121+ ✅ デフォルト有効 推奨
Edge 121+ ✅ デフォルト有効 対応
Arc ✅ デフォルト有効 対応
Safari ⚠️ Tech Preview のみ 非対応
Firefox ⚠️ Nightly のみ 非対応

WebGPU が使えるか確認する方法

Chrome で chrome://gpu を開き、「WebGPU」が「Hardware accelerated」になっていれば OK です。

Chrome の chrome://gpu ページで WebGPU の対応状況を確認する画面

モデルの入手

sd.keydrop.net はモデルを同梱していません。ユーザーが自身でモデルファイルを入手してアップロードする必要があります。

推奨: SD-Turbo(初心者向け)

最も手軽に試せるのは SD-Turbo です。1〜4 ステップで画像生成でき、VRAM 要求も 4GB と控えめです。

# ダウンロードスクリプト(開発環境のみ)

./scripts/download-sd-turbo.sh ~/Downloads/sd-turbo

スクリプトが使えない環境では、Hugging Face の schmuell/sd-turbo-ort-web リポジトリから以下の 5 ファイルを手動ダウンロードしてください:

  • text_encoder/model.onnx(約 650MB) → text_encoder.onnx にリネーム
  • unet/model.onnx(約 1.6GB) → unet.onnx にリネーム
  • vae_decoder/model.onnx(約 95MB) → vae_decoder.onnx にリネーム
  • tokenizer/vocab.json(約 1MB)
  • tokenizer/merges.txt(約 500KB)
重要: ファイル名に text_encoder / unet / vae が含まれている必要があります(アプリがファイル名で自動分類するため)。

その他のモデル

SD 1.5 系や SDXL の ONNX 変換済みモデルも対応しています。Hugging Face で onnx stable-diffusionXenova/stable-diffusion-v1-5 などで検索してください。 SDXL は VRAM 8GB 以上が推奨です。

おすすめモデル一覧

以下は sd.keydrop.net での動作確認状況をまとめたモデルリストです。

SD-Turbo / 少ステップ系(推奨・初心者向け)

1〜8 ステップで画像生成が完了する蒸留モデル。ブラウザ環境で最も快適に使えます。

モデル名 入手先 ステップ数 UNet (fp16) 変換 動作 特徴
SD-Turbo ORT Web schmuell/sd-turbo-ort-web 1〜4 ~1.6GB 不要 ✅ 確認済み 最もおすすめ。ORT Web 向け最適化済み。ダウンロードしてそのまま使える
SD-Turbo stabilityai/sd-turbo 1〜4 ~1.7GB Colab/ローカル Stability AI 公式。CFG 不要
LCM DreamShaper v7 SimianLuo/LCM_Dreamshaper_v7 4〜8 ~1.7GB Colab/ローカル ⚠️ 要テスト DreamShaper ベースの LCM。画風のバリエーション
SD-Turbo と LCM の違い:
  • SD-Turbo: SD 2.1 ベース。1 step で生成可能。CFG 不要。LoRA 非対応。画風は固定
  • LCM (Latent Consistency Model): SD 1.5 系ベースの蒸留。4〜8 step。ベースモデルの画風を引き継ぐため種類が豊富。LoRA も利用可能(ベースモデル依存)
LCM モデルの注意: sd.keydrop.net のスケジューラ(Euler Ancestral)は SD-Turbo 向けに最適化されています。LCM は専用スケジューラ(LCM Scheduler)を前提としているため、生成結果が期待通りにならない場合があります。確実に動作するのは SD-Turbo ORT Web です。

SD 1.5 系(高品質・LoRA 豊富)

モデル名 入手先 特徴 UNet サイズ (ONNX fp32) 動作
Stable Diffusion 1.5 (base) Hugging Face (runwayml/stable-diffusion-v1-5) ベースモデル。LoRA の互換性が最も高い ~1.7GB
Anything V5 CivitAI アニメ系の定番 ~1.7GB
Realistic Vision V5.1 CivitAI フォトリアル系の定番 ~1.7GB
DreamShaper 8 CivitAI 汎用。写真からイラストまで ~1.7GB
MeinaMix V11 CivitAI アニメ・イラスト特化 ~1.7GB
CounterfeitV3.0 CivitAI アニメ系、高品質 ~1.7GB
SD 1.5 系は ONNX 変換が必要です(変換ガイドを参照)。「weight-only fp16」変換により UNet ~0.85GB でブラウザで十分動作します。 optimum の dtype='fp16' で出力された純粋な fp16 ONNX モデルは ONNX Runtime Web で正しく動作しないため、必ず変換ガイドの手順に従ってください。

SDXL 系(現時点では非対応)

モデル名 UNet サイズ (fp16) 動作 理由
Nova Anime XL ~4.8GB ブラウザのタブメモリ上限超過
Animagine XL 3.1 ~4.8GB 同上
Juggernaut XL ~4.8GB 同上
RealVisXL ~4.8GB 同上
Pony Diffusion V6 XL ~4.8GB 同上
SDXL 系はすべて UNet が fp16 でも ~4.8GB あり、ブラウザの 1 タブのメモリ上限(4〜8GB)を超えるため現時点では動作しません。 SDXL を使いたい場合は AUTOMATIC1111ComfyUI 等のネイティブツールをご検討ください。

SDXL 軽量モデル(動作の可能性あり)

SDXL の UNet を蒸留(distillation)して小型化したモデルです。解像度は SDXL と同じ 1024×1024 を維持しつつ、UNet のパラメータ数を大幅に削減しています。

モデル名 入手先 パラメータ数 UNet (fp16 推定) 解像度 動作見込み 特徴
Segmind Vega Hugging Face 0.74B ~1.4GB 1024×1024 ✅ 可能性高い SDXL の UNet を約 1/3 に蒸留。SD-Turbo 並のサイズ
SSD-1B Hugging Face 1.3B ~2.4GB 1024×1024 ⚠️ 要テスト SDXL の UNet を約半分に蒸留。ブラウザのメモリ上限ギリギリ
  • SDXL と同じ VAE / テキストエンコーダを使うため、1024×1024 で生成可能
  • 一部の SDXL 向け LoRA も利用可能(互換性は限定的)
  • Colab での変換時は StableDiffusionXLPipeline.from_pretrained("segmind/Segmind-Vega") を使用(from_single_file ではなく from_pretrained
# Google Colab のセル 4 を以下に差し替えて使用
from diffusers import StableDiffusionXLPipeline
import torch
pipe = StableDiffusionXLPipeline.from_pretrained(
    "segmind/Segmind-Vega",  # or "segmind/SSD-1B"
    torch_dtype=torch.float16
)
pipe.save_pretrained('./model-diffusers')
# 以降は通常の SDXL 変換と同じ手順

SDXL-Turbo / Lightning(将来対応の可能性)

SDXL-Turbo や SDXL-Lightning は SDXL ベースですが、ステップ数が少ないためやや軽量です。 ただし UNet サイズは同じ ~4.8GB のため、現時点では同様に動作しません。 ブラウザのメモリ制限が緩和された場合に対応を検討します。

ライセンスに関する注意:CivitAI のモデルはライセンスが作者ごとに異なります。商用利用不可の場合がありますので、各モデルのライセンスを必ず確認してください。
fp16 モデルについて:schmuell/sd-turbo-ort-web のような特別にエクスポートされた公式 ONNX モデルはそのまま利用できます。 ただし、optimum の dtype='fp16' で出力された純粋な fp16 モデルは ONNX Runtime Web で正しく動作しません(出力がほぼゼロ値になる)。SD 1.5 系は必ず「weight-only fp16」変換ガイドの手順で変換してください。

モデルの読み込み

  1. 「画像生成」タブを開きます。左サイドバーにモデル選択パネルがあります。
  2. 「ここにファイルをドロップ」エリアに、5 ファイルすべてを一度にドラッグ&ドロップします。 モデルファイルをドロップエリアにドラッグしている画面
  3. 世代を選択(SD1.5 / SDXL / SD3)。ファイル名から自動推測されることが多いので、変更が不要な場合はそのまま。
  4. 「モデルを読み込む」ボタンをクリック。
  5. 進捗表示が始まります:
    • 📥 Loading (10%): Reading text_encoder — ファイル読み込み
    • 🔧 Compiling shaders (10%): Compiling text_encoder for WebGPU — WebGPU シェーダーコンパイル
    • UNet (50%) → VAE (85%) → Tokenizer (95%) と進む
    初回はシェーダーコンパイルで数十秒〜数分かかることがあります。2 回目以降はブラウザキャッシュにより高速化されます。
  6. Model loaded: SD-Turbo (unet.onnx)」のトーストが表示されれば成功です。 モデルロード完了のトースト通知が表示された画面

OPFS キャッシュからの復元

一度アップロードしたモデルは OPFS(Origin Private File System) に自動保存されます。 次回以降は、ドロップゾーンの下にある「📦 Load from OPFS cache」ボタンをクリックするだけで復元できます。

画像を生成する

プロンプト入力

中央のパネルにプロンプト(Positive / Negative)を入力します。CLIP ViT-L は英語で学習されているため、英語でのプロンプトを推奨します。

例:

Prompt: a cute orange tabby cat sitting on a red sofa, photorealistic, 4k

Negative: blurry, low quality, watermark

生成パラメータ

項目 説明 SD-Turbo 推奨値
幅 / 高さ 出力画像の解像度 512 / 512
Steps サンプリングステップ数(多いほど精緻だが遅い) 1(最速)〜 4
CFG Scale プロンプトへの忠実度(高いほど忠実だがアーティファクトが出やすい) 0(Turbo は内部で無効化)
Seed ノイズの初期値。同じ seed + 同じ設定 → 同じ画像 任意の整数

生成実行

  1. パラメータを設定したら「生成」ボタンをクリック
  2. 進捗バーが表示されます(ステップ数に応じた進行) 生成中の進捗バー
  3. 完了すると右パネルに画像が表示されます 生成結果のプレビュー表示
  4. 「Download PNG」ボタンでローカルに保存

PNG メタデータ

ダウンロードされた PNG には、生成パラメータ(プロンプト / サイズ / Steps / CFG / Seed / モデル名 / エンジン)が tEXt チャンクとして自動埋込されます。AUTOMATIC1111 や ComfyUI の「PNG Info」機能で読み取れます。

キャンセル

生成中に「キャンセル」ボタンを押すと、Worker に中断指令が送られます。

LoRA について

LoRA(Low-Rank Adaptation)は、ベースモデルに追加のスタイルやキャラクター表現を注入する軽量な追加学習手法です。 sd.keydrop.net では事前マージ方式を採用しています。

ワークフロー:

  1. ベースモデル(.safetensors)と LoRA(.safetensors)を用意
  2. 「LoRA マージ」タブでマージを実行
  3. マージ済み .safetensors をダウンロード
  4. オフラインで ONNX に変換(別途ツールが必要)
  5. 変換した ONNX モデルをアプリにアップロードして生成
※ 画像生成時のリアルタイム LoRA 適用(動的マージ)は現状非対応です。

LoRA マージ手順

  1. 「LoRA マージ」タブを開きます。 LoRA マージタブの初期画面
  2. ベースモデル(.safetensors 形式)をドロップエリアに投下します。
    例: v1-5-pruned-emaonly.safetensors
  3. 「+ LoRA を追加」ボタンで LoRA ファイル(.safetensors)を追加します。複数追加可能。
  4. 各 LoRA の weight スライダーを調整します。
    • 1.0 — 通常強度
    • 0.5 — 弱め
    • 1.5 — 強め
    • -1.0 — 逆効果
  5. マージアルゴリズムを選択(現状は「Pure TypeScript」のみ対応)。
  6. 「マージ実行」ボタンをクリック。進捗バーが表示されます。 マージ実行中の進捗バー
  7. 完了後:
    • 「Download .safetensors」 — マージ済みファイルを PC に保存
    • 「Save to OPFS cache」 — ブラウザ内ストレージに保存

マージ結果のメタデータ

出力ファイルの __metadata__ には以下が記録されます:

{
  "format": "pt",
  "merged_with": "my-lora.safetensors@1.0; other-lora.safetensors@0.5",
  "merged_at": "2026-04-10T...",
  "merged_by": "sd.keydrop.net pure-ts",
  "unmatched_lora_modules": "0"
}

unmatched_lora_modules がゼロでない場合は、LoRA のキー名がベースモデルのキー名にマッチしなかったモジュールがあることを示しています。

safetensors → ONNX 変換ガイド

CivitAI / Hugging Face のモデルを sd.keydrop.net で使うための変換手順です。 変換方法は 2 つあります。

方法 対象 所要時間 必要なもの
方法 1: Google Colab(推奨) SD 1.5 / SDXL 全て 10〜15 分 Google アカウントのみ
方法 2: ローカルスクリプト SD 1.5 のみ実用的 5〜30 分 Python 3.12 + NVIDIA GPU(SDXL は数時間かかり非推奨)
SDXL モデルの変換には Google Colab を強く推奨します。 SDXL は変換に GPU メモリが多く必要なため、Colab の NVIDIA T4 GPU を使うと 10〜15 分で完了します。 SD 1.5 系は「weight-only fp16」アプローチにより GPU 不要で、CPU のみのローカル環境でも変換できます。

方法 1:Google Colab で変換(推奨)

ブラウザから無料の GPU を使って変換します。PC のスペックに関係なく、SD 1.5 / SDXL どちらも変換できます。

手順

  1. Google Colab を開き、「新しいノートブック」を作成
  2. メニューの 「ランタイム」→「ランタイムのタイプを変更」→ ハードウェアアクセラレータを「T4 GPU」に設定して保存
  3. 以下の 6 つのセルを順番にコピー&ペーストして実行(各セルの左にある ▶ ボタンをクリック)

セル 1: ライブラリインストール(約 3 分)

!pip install -q optimum[onnxruntime-gpu] diffusers transformers torch accelerate
print("✅ インストール完了")

セル 2: モデルファイルをアップロード

from google.colab import files
print("safetensors ファイルを選択してください...")
uploaded = files.upload()
model_filename = list(uploaded.keys())[0]
print(f"✅ アップロード完了: {model_filename} ({len(uploaded[model_filename]) / 1e9:.1f}GB)")

ファイル選択ダイアログが表示されるので、CivitAI 等からダウンロードした .safetensors を選択してください。

セル 3: モデルタイプを選択

# SD 1.5 系の場合は "sd15" に変更してください
MODEL_TYPE = "sdxl"

if MODEL_TYPE == "sdxl":
    PIPELINE_CLASS = "StableDiffusionXLPipeline"
    TASK = "stable-diffusion-xl"
else:
    PIPELINE_CLASS = "StableDiffusionPipeline"
    TASK = "stable-diffusion"
print(f"✅ モデルタイプ: {MODEL_TYPE}")
SD 1.5 系の場合は MODEL_TYPE = "sd15" に変更してから実行してください。

セル 4: 変換実行(約 10〜15 分)

import torch, os, shutil, gc
from pathlib import Path

# Step 1: safetensors → diffusers(fp32 で読み込み)
print("📦 Step 1/4: diffusers 形式に変換中...")
if MODEL_TYPE == "sdxl":
    from diffusers import StableDiffusionXLPipeline
    pipe = StableDiffusionXLPipeline.from_single_file(model_filename, torch_dtype=torch.float32)
else:
    from diffusers import StableDiffusionPipeline
    pipe = StableDiffusionPipeline.from_single_file(model_filename, torch_dtype=torch.float32)
pipe.save_pretrained('./model-diffusers')
del pipe; torch.cuda.empty_cache()
print("✅ diffusers 変換完了")

# Step 2: ONNX (fp32) エクスポート
# ⚠️ dtype='fp16' は使わない — fp16 グラフはブラウザの ONNX Runtime Web で
#    正しく動作しないため、fp32 でエクスポートする
print("🔧 Step 2/4: ONNX (fp32) エクスポート中...(10〜15 分お待ちください)")
from optimum.exporters.onnx import main_export
try:
    main_export(model_name_or_path='./model-diffusers', output=Path('./model-onnx'), task=TASK, no_post_process=True)
except Exception as e:
    print(f"⚠️ 警告(ファイルは出力済み): {e}")
print("✅ ONNX エクスポート完了")

# Step 3: 重みを fp16 に変換(計算グラフは fp32 互換のまま)
print("🔄 Step 3/4: 重みを fp16 に変換中...")
import onnx
import numpy as np
from onnx import TensorProto, numpy_helper, helper

def convert_weights_to_fp16(model):
    init_names = set()
    for init in model.graph.initializer:
        if init.data_type == TensorProto.FLOAT and init.name:
            init_names.add(init.name)
    if not init_names:
        return model
    print(f"    Converting {len(init_names)} initializers to fp16...")
    for init in model.graph.initializer:
        if init.name in init_names:
            np_data = numpy_helper.to_array(init)
            np_fp16 = np_data.astype(np.float16)
            new_tensor = numpy_helper.from_array(np_fp16, init.name)
            init.CopyFrom(new_tensor)
    cast_map = {}
    cast_nodes = []
    for name in init_names:
        cast_out = name + '__fp32'
        cast_node = helper.make_node(
            'Cast', inputs=[name], outputs=[cast_out],
            to=int(TensorProto.FLOAT), name=name + '__cast',
        )
        cast_nodes.append(cast_node)
        cast_map[name] = cast_out
    for node in model.graph.node:
        for i in range(len(node.input)):
            if node.input[i] in cast_map:
                node.input[i] = cast_map[node.input[i]]
    for out in model.graph.output:
        if out.name in cast_map:
            out.name = cast_map[out.name]
    for inp in model.graph.input:
        if inp.name in init_names:
            inp.type.tensor_type.elem_type = int(TensorProto.FLOAT16)
    for node in reversed(cast_nodes):
        model.graph.node.insert(0, node)
    print(f"    Inserted {len(cast_nodes)} Cast nodes")
    return model

os.makedirs('sd-ready', exist_ok=True)
components = [('text_encoder','text_encoder'),('text_encoder_2','text_encoder_2'),('unet','unet'),('vae_decoder','vae_decoder')]
for src, dst in components:
    p = f'model-onnx/{src}/model.onnx'
    if not os.path.exists(p): continue
    print(f"  {dst}: loading fp32 model...")
    model = onnx.load(p, load_external_data=True)
    print(f"  {dst}: converting weights to fp16...")
    model = convert_weights_to_fp16(model)
    out = os.path.abspath(f'sd-ready/{dst}.onnx')
    onnx.save(model, out)
    del model; gc.collect()
    print(f"  {dst}: {os.path.getsize(out)/1e6:.0f}MB")

# Step 4: tokenizer コピー
print("📂 Step 4/4: tokenizer ファイルをコピー中...")
for f in ['vocab.json','merges.txt']:
    s = f'model-onnx/tokenizer/{f}'
    if os.path.exists(s): shutil.copy2(s, f'sd-ready/{f}')
print("\n🎉 変換完了!セル 5 でダウンロードしてください。")

セル 5: ZIP に圧縮してダウンロード

import subprocess, os
subprocess.run(['zip', '-r', '-0', 'sd-ready.zip', 'sd-ready/'], check=True)
print(f"📦 sd-ready.zip ({os.path.getsize('sd-ready.zip')/1e9:.1f}GB)")
from google.colab import files
files.download('sd-ready.zip')

ファイルが大きすぎてダウンロードが失敗する場合は、下のセル 5b を使ってください。

セル 5b: Google Drive に保存(大きなファイルの場合)

from google.colab import drive
import shutil
drive.mount('/content/drive')
shutil.copytree('sd-ready', '/content/drive/MyDrive/sd-ready', dirs_exist_ok=True)
print("✅ Google Drive の「マイドライブ/sd-ready」に保存しました")

ダウンロード後

  1. sd-ready.zip を解凍(または Google Drive からコピー)
  2. sd.keydrop.net を開く
  3. sd-ready/ 内の全ファイルをドロップ
  4. 世代を選択して「モデルを読み込む」

方法 2:ローカルスクリプトで変換

注意:SDXL モデルの変換には Google Colab を推奨します。 SDXL は変換に GPU メモリが多く必要です。SDXL の場合は方法 1(Google Colab)を使ってください。 SD 1.5 / SD-Turbo は「weight-only fp16」アプローチにより GPU 不要で、CPU のみのローカル環境でも変換できます。
必要環境:
  • Python 3.10〜3.12(3.13 以上は非対応)
  • SD 1.5: RAM 8GB 以上
  • SDXL: NVIDIA GPU + RAM 16GB 以上
  • ディスク空き容量 20GB 以上

まずスクリプトをダウンロード

以下のリンクからスクリプトをダウンロードし、変換したいモデルファイル(.safetensors)と同じフォルダに保存してください。

ダウンロードしたら、ターミナルでスクリプトのあるフォルダに cd してから実行してください。

macOS / Linux

# スクリプトをダウンロードしたフォルダに移動
cd ~/Downloads

# SD 1.5 モデルの場合
bash convert-to-onnx.sh your-model.safetensors sd15
# SDXL モデルの場合
bash convert-to-onnx.sh novaAnimeXL.safetensors sdxl
# 自動判別(ファイル名に xl/sdxl を含むかで判定)
bash convert-to-onnx.sh your-model.safetensors

Windows(Git Bash または WSL)

コマンドは macOS / Linux と同じです。Git Bash または WSL から実行してください。

bash convert-to-onnx.sh your-model.safetensors sd15
出力:sd-ready/ フォルダにアップロード用ファイルがすべて揃います。
次のステップ:sd-ready/ 内の全ファイルを sd.keydrop.net にドラッグ&ドロップしてください。

スクリプトが行う処理

  1. Python 3.10〜3.12 を自動検出
  2. 仮想環境を作成(sd-convert-env
  3. 必要ライブラリをインストール(optimum, diffusers, transformers, torch 等)
  4. safetensors → diffusers → ONNX に変換
  5. 重みを weight-only fp16 に変換 + Cast(fp16→fp32) ノード挿入、単一 .onnx ファイルとして保存
  6. sd-ready/ にリネームして出力
スクリプトが使えない場合(手動手順)

Step 1:Python 3.12 のインストール

python.org から Python 3.12 をインストールしてください。 Windows の場合は 「Add Python to PATH」にチェックを忘れずに。

Step 2:仮想環境 + ライブラリインストール

Windows(コマンドプロンプト)
python -m venv sd-convert-env
sd-convert-env\Scripts\activate
pip install "optimum[onnxruntime]" diffusers transformers torch --extra-index-url https://download.pytorch.org/whl/cpu
macOS / Linux
python3.12 -m venv sd-convert-env
source sd-convert-env/bin/activate
pip install "optimum[onnxruntime]" diffusers transformers torch --extra-index-url https://download.pytorch.org/whl/cpu

Step 3:変換コマンド

SD 1.5
python3 -c "
from diffusers import StableDiffusionPipeline; import torch
pipe = StableDiffusionPipeline.from_single_file('your-model.safetensors', torch_dtype=torch.float16)
pipe.save_pretrained('./model-diffusers')
"
optimum-cli export onnx --model ./model-diffusers --task stable-diffusion ./model-onnx
SDXL
python3 -c "
from diffusers import StableDiffusionXLPipeline; import torch
pipe = StableDiffusionXLPipeline.from_single_file('your-sdxl-model.safetensors', torch_dtype=torch.float16)
pipe.save_pretrained('./model-diffusers')
"
optimum-cli export onnx --model ./model-diffusers --task stable-diffusion-xl ./model-onnx

Windows の場合は python3python に読み替えてください。

Step 4:外部データ統合 + fp16 変換

model-onnx/ 内に .onnx_data ファイルがある場合(SDXL で多い)、以下で統合と fp16 変換を行います。

pip install onnx
python3 -c "
import onnx, os, numpy as np
for sub in ['unet', 'text_encoder_2']:
    path = f'model-onnx/{sub}/model.onnx'
    data = path + '_data'
    if not os.path.exists(data): continue
    print(f'Merging {sub}...')
    m = onnx.load(path, load_external_data=True)
    # fp16 conversion for large models
    for init in m.graph.initializer:
        if init.data_type == 1:  # FLOAT
            arr = np.frombuffer(init.raw_data, dtype=np.float32).astype(np.float16)
            init.raw_data = arr.tobytes()
            init.data_type = 10  # FLOAT16
    onnx.save_model(m, f'model-onnx/{sub}/model_fp16.onnx', save_as_external_data=False)
    print(f'  {sub} done')
print('All done!')
"

Step 5:リネーム

SD 1.5(macOS / Linux)
mkdir -p sd-ready
cp model-onnx/text_encoder/model.onnx sd-ready/text_encoder.onnx
cp model-onnx/unet/model.onnx sd-ready/unet.onnx
cp model-onnx/vae_decoder/model.onnx sd-ready/vae_decoder.onnx
cp model-onnx/tokenizer/vocab.json sd-ready/vocab.json
cp model-onnx/tokenizer/merges.txt sd-ready/merges.txt
SDXL(macOS / Linux)
mkdir -p sd-ready
cp model-onnx/text_encoder/model.onnx sd-ready/text_encoder.onnx
cp model-onnx/text_encoder_2/model_fp16.onnx sd-ready/text_encoder_2.onnx
cp model-onnx/unet/model_fp16.onnx sd-ready/unet.onnx
cp model-onnx/vae_decoder/model.onnx sd-ready/vae_decoder.onnx
cp model-onnx/tokenizer/vocab.json sd-ready/vocab.json
cp model-onnx/tokenizer/merges.txt sd-ready/merges.txt

Windows の場合は cpcopymkdir -pmkdir/\ に読み替えてください。

sd.keydrop.net にアップロード

  1. sd.keydrop.net を開く
  2. sd-ready/ フォルダ内のすべてのファイルを生成タブのドロップエリアにドラッグ&ドロップ
  3. 世代を選択(SD 1.5 系なら SD1.5、SDXL 系なら SDXL
  4. 「モデルを読み込む」をクリック
  5. 読み込みが完了したらプロンプトを入力して生成
パラメータ SD 1.5 推奨値 SDXL 推奨値
幅 × 高さ 512 × 512 1024 × 1024
Steps 20〜30 20〜30
CFG Scale 7〜10 7
VRAM 目安 6GB 以上 8GB 以上

トラブルシューティング

RuntimeError: Error(s) in loading state_dict

原因:モデルの形式がコマンドと合っていない(SD 1.5 のコマンドで SDXL を変換しようとしている等)。

対処:モデルの種類を CivitAI のページで確認し、正しい世代(sd15 / sdxl)を指定してください。

torch.cuda.OutOfMemoryError / メモリ不足

対処:他のアプリを閉じてメモリを解放してください。SDXL の変換には RAM 16GB 以上を推奨します。

ModuleNotFoundError: No module named 'xxx'

対処:仮想環境が有効か確認し、ライブラリのインストールコマンドを再実行してください。

FileNotFoundError: 'your-model.safetensors'

対処:ファイルパスが正しいか確認してください。スクリプト使用時はフルパスを指定するのが確実です。

protobuf serialize error / Message serialization exceeded maximum protobuf size

原因:ONNX ファイルが 2GB の protobuf 上限を超えている(SDXL の UNet 等)。

対処:fp16 変換が必要です。スクリプトを使えば自動で処理されます。手動の場合は Step 4 の fp16 変換を実行してください。

NormalizedConfig.__init__() got multiple values for argument

原因:Python 3.13 以上を使っている。 対処:Python 3.12 で仮想環境を作り直してください。

Validation ... max diff = ... / the model was saved nonetheless

これはエラーではありません。変換は成功しています。 fp16 の丸め誤差が許容値を超えたという警告ですが、the model was saved nonetheless と表示されていればファイルは正常に出力されています。

LoRA マージ済みモデルの変換

sd.keydrop.net の LoRA マージツールで出力した *-merged.safetensors も、同じスクリプトで変換できます。

bash scripts/convert-to-onnx.sh ~/Downloads/v1-5-pruned-emaonly-merged.safetensors sd15

設定

「設定」タブから以下を変更できます:

設定画面のスクリーンショット

推論エンジン

現在対応しているエンジンは ONNX Runtime Web のみです。 Transformers.js / Ratchet はスタブとして存在しますが、SD パイプライン非対応のため選択できません。

言語

日本語(既定)/ 英語を切り替えられます。ブラウザの navigator.language から自動判定しますが、手動で変更した場合は localStorage に保存されます。

テーマ

ライトモード / ダークモードを切り替えます。OS のカラースキーム設定にも追従します。

利用統計(GA4)

「基本計測」(デフォルト ON)と「詳細計測」(デフォルト OFF、オプトイン)の 2 段階。

  • 基本計測: 生成ボタン押下数、画像 DL 数(匿名カウンターのみ)
  • 詳細計測: エラーログ、プロンプト本文、モデル名(明示的にオンにしない限り送信されない)

ブラウザの Do Not Track 設定は自動的に尊重されます。

生成履歴

生成した画像は IndexedDB に自動保存されます(画像 Blob + 全パラメータ)。 設定タブの「History management」カードで直近 30 件をサムネイル付きで確認できます。

生成履歴一覧の画面

「Clear all history」ボタンで一括削除できます(確認ダイアログ付き)。 履歴はブラウザ内のみに保存され、外部には送信されません。

ストレージ管理

設定タブの「Storage management」カードで、OPFS に保存されたモデルファイルの管理ができます:

  • OPFS 使用量とクォータの表示
  • キャッシュ済みファイル一覧(名前 / サイズ / 日時)
  • ファイルごとの個別削除
OPFS はブラウザのプライベートストレージです。「閲覧データの削除」やシークレットウィンドウでは消える可能性があります。重要なモデルファイルは PC 側にもバックアップしてください。

トラブルシューティング

Missing required ONNX components

原因: ファイル名に text_encoder / unet / vae が含まれていない、またはファイルが足りない。

対処: ファイル名を確認し、必要なら手動リネーム。エラーメッセージには各ファイルの分類結果が診断情報として含まれます。

WebAssembly.Module doesn't parse

原因: ORT の WASM ファイルが正しく配信されていない。

対処: 開発サーバの場合、vite-plugin-static-copy が設定されているか確認。本番の場合、/ort-wasm/ パスが有効か確認。

GPU VRAM が不足しています

対処:

  • 画像サイズを小さくする(512×512 → 384×384)
  • 他のタブやアプリを閉じて VRAM を解放
  • fp16 量子化されたモデルを使う(SD-Turbo は既に fp16)

画質が悪い / ノイズだらけ

原因:

  • SD 1.5 系は Steps 20〜50 が必要(SD-Turbo は 1〜4 で OK)
  • 画像サイズが学習解像度と合っていない(SD 1.5 は 512、SDXL は 1024)
  • CFG Scale が不適切(SD 1.5 では 7〜10 が一般的、SD-Turbo は 0)

OPFS に保存したのに消えた

ブラウザの「閲覧データの削除」設定や、シークレットウィンドウの利用が原因です。通常ウィンドウを使い、設定を確認してください。

LoRA マージで unmatched modules が多い

LoRA のキー命名規則とベースモデルのテンソル名が一致していない可能性があります。 現状のマッピングは Kohya 形式(SD 1.5 系)を前提としています。SDXL 向け LoRA や独自命名の LoRA は未対応のことがあります。

プライバシー

送信されないもの

  • アップロードされたモデルファイル / LoRA ファイル本体
  • 生成された画像
  • 生成履歴

送信される可能性があるもの(GA4)

  • 基本計測(デフォルト ON): 生成ボタン押下数 / 画像 DL 数(匿名メタ付き)
  • 詳細計測(オプトイン、デフォルト OFF): エラーログ / プロンプト / モデル名

設定画面からいつでも無効化可能。Do Not Track も尊重。VITE_GA_MEASUREMENT_ID 未設定のビルドでは計測機能は完全無効です。

Tips

Seed を固定して微調整

同じ Seed で Steps や CFG Scale だけを変えると、構図を保ったまま品質を調整できます。

LoRA の weight を段階的に変える

weight=0.3 → 0.5 → 1.0 と段階的にマージして効果を確認すると、過剰適用を防げます。

OPFS キャッシュの活用

モデルロードは初回だけ時間がかかりますが、OPFS に保存されれば 2 回目以降は数秒で復元できます。「📦 Load from OPFS cache」を活用しましょう。

複数モデルの切替

別のモデルを試すには、ページをリロードしてから新しいファイルをドロップしてください。現状、複数モデルの同時保持には対応していません。

PNG メタデータの活用

生成画像の PNG ファイルには生成条件が自動記録されています。「この画像、どんな設定で作ったっけ?」と思ったら、AUTOMATIC1111 の PNG Info やフリーツールで確認できます。