Pythonと[FLUX.1-dev]でローカル環境に生成AIをインストールした時の手順を備忘録的に投稿しておきます。
ローカル環境に生成AIをインストール
先回インストールしてみた[FLUX.1-dev]でプロンプトに入力したテキストから画像を生成するまでのワークフローを作成してみた。
[FLUX.1-dev]をインストールする手順については別記事をご覧ください。
ワークフローを作成
インストールした[ComfyUI]でテキストから画像生成するには、フローチャートのような[ワークフロー]を作成する必要があります。
[ワークフロー]は[ノード]を繋ぎ合わせて設計図で、流れに沿って処理が進みます。
配置は[ノードライブラリ]で処理を選んで行うのですが、沢山の種類のノードから何を使えばいいのか、最初は面喰います。
簡単なワークフロー
必要最低限のノードを使って[FLUX.1-dev]で画像を生成できたワークフローの作成手順を紹介します。
各種モデル(Checkpoint、Clip、VAEなど)ファイルが所定のフォルダーに保存されている必要があります。
配置するノードは、こんな感じ。(名前を[ノードライブラリ]で検索すると表示されます)
| 名前 | 数量 |
| デュアルCLIPを読み込む | 1 |
| CLIPテキストエンコード(プロンプト) | 2 |
| 拡散モデルを読み込む | 1 |
| 整数 | 2 |
| モデルサンプリングフラックス | 1 |
| 空のSD3潜在画像 | 1 |
| 基本スケジューラー | 1 |
| Kサンプラー選択 | 1 |
| カスタムサンプラー | 1 |
| VEAを読み込む | 1 |
| VEAデコード | 1 |
| 画像を保存 | 1 |
最初にプロンプトを作成するワークフロー
1.[デュアルCLIPを読み込む]ノードを配置して[clip_name]に[clip_l.safetensors]と[t5xxl_fp8_e4m3fn.safetensors]を設定します。
2.[CLIPテキストエンコード(プロンプト)]ノードを2つ配置して[デュアルCLIPを読み込む]ノードの[CLIP(クリップ)]ピンをぞれぞれ接続します。
3. それぞれ[CLIPテキストエンコード(プロンプト)]ノードのボックスにポジティブとネガティブのテキストを入力します。
今回はポジティブなキーワードとして “Green Apple”、ネガティブなキーワードとして “Orange” を入力しました。
モデルを作成するワークフロー
1.[拡散モデルを読み込む]ノードを配置して[unet_name]プロパティに[flux1-dev.safetensors]を設定します。
2.[モデルサンプリングフラックス]ノードを配置して[拡散モデルを読み込む]の[モデル]ピン同士を接続します。
3.[整数]ノードを2つ配置して、生成する画像のサイズ(幅と高さ)を[値]プロパティに設定します。
4.[モデルサンプリングフラックス]ノード[幅]と[高さ]ピンと[整数]ノードの[整数]ピンを接続します。
5.[空のSD3潜在画像]ノードを配置して[幅]と[高さ]ピンと[整数]ノードの[整数]ピンを接続します。
6.[基本スケジューラー]ノードを配置して[モデルサンプリングフラックス]ノードの[モデル]ピンと接続します。
[整数]ノードの[値]以外のプロパティは、既定値のままでも構いません。
サンプラーから画像を生成するワークフロー
1.[Kサンプラー選択]ノードを配置します。
2.[カスタムサンプラー]を配置して[Kサンプラー選択]ノードの[サンプラー]ピン同士を接続します。
3.[モデルサンプリングフラックス]ノードの[モデル]ピン、[空のSD3潜在画像]ノードの[潜在]ピン、[基本スケジューラー]ノードの[シグマ]ピンを[カスタムサンプラー]ノードのそれぞれのピンに接続します。
4.[CLIPテキストエンコード(プロンプト)]ノードの[条件付け]ピンを[カスタムサンプラー]ノードの[ポジティブ]と[ネガティブ]ピンに接続します。
5.[VEAを読み込む]ノードを配置して[vea_name]プロパティに[ae.safetensors]を設定します。
6.[VEAデコード]ノードを配置して[VEAを読み込む]ノードの[VEA]ピンを接続します。
7.[カスタムサンプラー]ノードの[出力]ピンと[VEAデコード]ノードの[サンプル]ピンを接続します。
8.[画像を保存]ノードを配置して[VEAデコード]ノードの[画像]ピンと接続します。
実行すると、”緑のりんご” っぽい画像が[output]フォルダーに出力されます。
ワークフローのJSON
最後に作成したワークフローのJSONを貼り付けておきます。
保存したファイルをComfyUIの[メニュー|ファイル|開く]で選択するとワークフローが表示される(はず)です。
{
"id": "00000000-0000-0000-0000-000000000000",
"revision": 0,
"last_node_id": 24,
"last_link_id": 24,
"nodes": [
{
"id": 7,
"type": "PrimitiveInt",
"pos": [
191.02205519937897,
180.4999625051073
],
"size": [
270,
82
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [
{
"localized_name": "値",
"name": "value",
"type": "INT",
"widget": {
"name": "value"
},
"link": null
}
],
"outputs": [
{
"localized_name": "整数",
"name": "INT",
"type": "INT",
"links": [
3,
5
]
}
],
"title": "整数(幅)",
"properties": {
"Node name for S&R": "PrimitiveInt"
},
"widgets_values": [
512,
"fixed"
]
},
{
"id": 8,
"type": "PrimitiveInt",
"pos": [
196.57753615641025,
322.20369785667003
],
"size": [
270,
82
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [
{
"localized_name": "値",
"name": "value",
"type": "INT",
"widget": {
"name": "value"
},
"link": null
}
],
"outputs": [
{
"localized_name": "整数",
"name": "INT",
"type": "INT",
"links": [
4,
6
]
}
],
"title": "整数(高さ)",
"properties": {
"Node name for S&R": "PrimitiveInt"
},
"widgets_values": [
512,
"fixed"
]
},
{
"id": 9,
"type": "ModelSamplingFlux",
"pos": [
581.8369355704735,
115.09261387229476
],
"size": [
295.9,
130
],
"flags": {},
"order": 7,
"mode": 0,
"inputs": [
{
"localized_name": "モデル",
"name": "model",
"type": "MODEL",
"link": 7
},
{
"localized_name": "最大シフト",
"name": "max_shift",
"type": "FLOAT",
"widget": {
"name": "max_shift"
},
"link": null
},
{
"localized_name": "基本シフト",
"name": "base_shift",
"type": "FLOAT",
"widget": {
"name": "base_shift"
},
"link": null
},
{
"localized_name": "幅",
"name": "width",
"type": "INT",
"widget": {
"name": "width"
},
"link": 3
},
{
"localized_name": "高さ",
"name": "height",
"type": "INT",
"widget": {
"name": "height"
},
"link": 4
}
],
"outputs": [
{
"localized_name": "モデル",
"name": "MODEL",
"type": "MODEL",
"links": [
10,
11
]
}
],
"properties": {
"Node name for S&R": "ModelSamplingFlux"
},
"widgets_values": [
1.15,
0.5,
1024,
1024
]
},
{
"id": 10,
"type": "EmptySD3LatentImage",
"pos": [
599.9203992545554,
316.17601652122073
],
"size": [
270,
106
],
"flags": {},
"order": 6,
"mode": 0,
"inputs": [
{
"localized_name": "幅",
"name": "width",
"type": "INT",
"widget": {
"name": "width"
},
"link": 5
},
{
"localized_name": "高さ",
"name": "height",
"type": "INT",
"widget": {
"name": "height"
},
"link": 6
},
{
"localized_name": "バッチサイズ",
"name": "batch_size",
"type": "INT",
"widget": {
"name": "batch_size"
},
"link": null
}
],
"outputs": [
{
"localized_name": "潜在",
"name": "LATENT",
"type": "LATENT",
"links": [
18
]
}
],
"properties": {
"Node name for S&R": "EmptySD3LatentImage"
},
"widgets_values": [
1024,
1024,
1
]
},
{
"id": 16,
"type": "SamplerCustom",
"pos": [
1271.7521540194416,
1363.5274627019708
],
"size": [
270,
230
],
"flags": {},
"order": 11,
"mode": 0,
"inputs": [
{
"localized_name": "モデル",
"name": "model",
"type": "MODEL",
"link": 11
},
{
"localized_name": "ポジティブ",
"name": "positive",
"type": "CONDITIONING",
"link": 24
},
{
"localized_name": "ネガティブ",
"name": "negative",
"type": "CONDITIONING",
"link": 23
},
{
"localized_name": "サンプラー",
"name": "sampler",
"type": "SAMPLER",
"link": 14
},
{
"localized_name": "シグマ",
"name": "sigmas",
"type": "SIGMAS",
"link": 13
},
{
"localized_name": "潜在画像",
"name": "latent_image",
"type": "LATENT",
"link": 18
},
{
"localized_name": "ノイズを追加",
"name": "add_noise",
"type": "BOOLEAN",
"widget": {
"name": "add_noise"
},
"link": null
},
{
"localized_name": "ノイズシード",
"name": "noise_seed",
"type": "INT",
"widget": {
"name": "noise_seed"
},
"link": null
},
{
"localized_name": "cfg",
"name": "cfg",
"type": "FLOAT",
"widget": {
"name": "cfg"
},
"link": null
}
],
"outputs": [
{
"localized_name": "出力",
"name": "output",
"type": "LATENT",
"links": [
21
]
},
{
"localized_name": "デノイズ出力",
"name": "denoised_output",
"type": "LATENT",
"links": null
}
],
"properties": {
"Node name for S&R": "SamplerCustom"
},
"widgets_values": [
true,
660327536536129,
"randomize",
8
]
},
{
"id": 24,
"type": "VAELoader",
"pos": [
1270.411976529209,
1649.8524685613452
],
"size": [
270,
58
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"localized_name": "vae_name",
"name": "vae_name",
"type": "COMBO",
"widget": {
"name": "vae_name"
},
"link": null
}
],
"outputs": [
{
"localized_name": "VAE",
"name": "VAE",
"type": "VAE",
"links": [
20
]
}
],
"properties": {
"Node name for S&R": "VAELoader"
},
"widgets_values": [
"ae.safetensors"
]
},
{
"id": 21,
"type": "SaveImage",
"pos": [
1599.4426458407315,
1481.2995437566583
],
"size": [
314.673828125,
270
],
"flags": {},
"order": 13,
"mode": 0,
"inputs": [
{
"localized_name": "画像",
"name": "images",
"type": "IMAGE",
"link": 22
},
{
"localized_name": "ファイル名_プレフィックス",
"name": "filename_prefix",
"type": "STRING",
"widget": {
"name": "filename_prefix"
},
"link": null
}
],
"outputs": [],
"properties": {},
"widgets_values": [
"ComfyUI"
]
},
{
"id": 17,
"type": "CLIPTextEncode",
"pos": [
464.4593439929781,
2753.91677435828
],
"size": [
400,
200
],
"flags": {},
"order": 9,
"mode": 0,
"inputs": [
{
"localized_name": "クリップ",
"name": "clip",
"type": "CLIP",
"link": 15
},
{
"localized_name": "テキスト",
"name": "text",
"type": "STRING",
"widget": {
"name": "text"
},
"link": null
}
],
"outputs": [
{
"localized_name": "条件付け",
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
23
]
}
],
"properties": {
"Node name for S&R": "CLIPTextEncode"
},
"widgets_values": [
"orange"
]
},
{
"id": 14,
"type": "KSamplerSelect",
"pos": [
458.68238121365596,
1427.4980092717947
],
"size": [
270,
58
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"localized_name": "サンプラー名",
"name": "sampler_name",
"type": "COMBO",
"widget": {
"name": "sampler_name"
},
"link": null
}
],
"outputs": [
{
"localized_name": "サンプラー",
"name": "SAMPLER",
"type": "SAMPLER",
"links": [
14
]
}
],
"properties": {
"Node name for S&R": "KSamplerSelect"
},
"widgets_values": [
"euler"
]
},
{
"id": 13,
"type": "BasicScheduler",
"pos": [
600.5067755168725,
509.1756947067021
],
"size": [
270,
106
],
"flags": {},
"order": 10,
"mode": 0,
"inputs": [
{
"localized_name": "モデル",
"name": "model",
"type": "MODEL",
"link": 10
},
{
"localized_name": "スケジューラ",
"name": "scheduler",
"type": "COMBO",
"widget": {
"name": "scheduler"
},
"link": null
},
{
"localized_name": "ステップ",
"name": "steps",
"type": "INT",
"widget": {
"name": "steps"
},
"link": null
},
{
"localized_name": "ノイズ除去",
"name": "denoise",
"type": "FLOAT",
"widget": {
"name": "denoise"
},
"link": null
}
],
"outputs": [
{
"localized_name": "シグマ",
"name": "SIGMAS",
"type": "SIGMAS",
"links": [
13
]
}
],
"properties": {
"Node name for S&R": "BasicScheduler"
},
"widgets_values": [
"simple",
20,
1
]
},
{
"id": 4,
"type": "UNETLoader",
"pos": [
190.19690615152737,
39.41693253684569
],
"size": [
270,
82
],
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"localized_name": "unet_name",
"name": "unet_name",
"type": "COMBO",
"widget": {
"name": "unet_name"
},
"link": null
},
{
"localized_name": "重みdtype",
"name": "weight_dtype",
"type": "COMBO",
"widget": {
"name": "weight_dtype"
},
"link": null
}
],
"outputs": [
{
"localized_name": "モデル",
"name": "MODEL",
"type": "MODEL",
"links": [
7
]
}
],
"properties": {
"Node name for S&R": "UNETLoader"
},
"widgets_values": [
"flux1-dev.safetensors",
"default"
]
},
{
"id": 1,
"type": "DualCLIPLoader",
"pos": [
153.67905461254088,
2508.7680954886514
],
"size": [
270,
130
],
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"localized_name": "clip_name1",
"name": "clip_name1",
"type": "COMBO",
"widget": {
"name": "clip_name1"
},
"link": null
},
{
"localized_name": "clip_name2",
"name": "clip_name2",
"type": "COMBO",
"widget": {
"name": "clip_name2"
},
"link": null
},
{
"localized_name": "タイプ",
"name": "type",
"type": "COMBO",
"widget": {
"name": "type"
},
"link": null
},
{
"localized_name": "デバイス",
"name": "device",
"shape": 7,
"type": "COMBO",
"widget": {
"name": "device"
},
"link": null
}
],
"outputs": [
{
"localized_name": "CLIP",
"name": "CLIP",
"type": "CLIP",
"links": [
1,
15
]
}
],
"properties": {
"Node name for S&R": "DualCLIPLoader"
},
"widgets_values": [
"t5xxl_fp8_e4m3fn.safetensors",
"clip_l.safetensors",
"flux",
"default"
]
},
{
"id": 2,
"type": "CLIPTextEncode",
"pos": [
460.77926591070377,
2500.7126228934367
],
"size": [
400,
200
],
"flags": {},
"order": 8,
"mode": 0,
"inputs": [
{
"localized_name": "クリップ",
"name": "clip",
"type": "CLIP",
"link": 1
},
{
"localized_name": "テキスト",
"name": "text",
"type": "STRING",
"widget": {
"name": "text"
},
"link": null
}
],
"outputs": [
{
"localized_name": "条件付け",
"name": "CONDITIONING",
"type": "CONDITIONING",
"links": [
24
]
}
],
"properties": {
"Node name for S&R": "CLIPTextEncode"
},
"widgets_values": [
"Cute Girl Nude Sitting Bed"
]
},
{
"id": 23,
"type": "VAEDecode",
"pos": [
1578.4853711825278,
1367.8776118718927
],
"size": [
258.10393560302737,
46
],
"flags": {},
"order": 12,
"mode": 0,
"inputs": [
{
"localized_name": "サンプル",
"name": "samples",
"type": "LATENT",
"link": 21
},
{
"localized_name": "vae",
"name": "vae",
"type": "VAE",
"link": 20
}
],
"outputs": [
{
"localized_name": "画像",
"name": "IMAGE",
"type": "IMAGE",
"links": [
22
]
}
],
"properties": {
"Node name for S&R": "VAEDecode"
},
"widgets_values": []
}
],
"links": [
[
1,
1,
0,
2,
0,
"CLIP"
],
[
3,
7,
0,
9,
3,
"INT"
],
[
4,
8,
0,
9,
4,
"INT"
],
[
5,
7,
0,
10,
0,
"INT"
],
[
6,
8,
0,
10,
1,
"INT"
],
[
7,
4,
0,
9,
0,
"MODEL"
],
[
10,
9,
0,
13,
0,
"MODEL"
],
[
11,
9,
0,
16,
0,
"MODEL"
],
[
13,
13,
0,
16,
4,
"SIGMAS"
],
[
14,
14,
0,
16,
3,
"SAMPLER"
],
[
15,
1,
0,
17,
0,
"CLIP"
],
[
18,
10,
0,
16,
5,
"LATENT"
],
[
20,
24,
0,
23,
1,
"VAE"
],
[
21,
16,
0,
23,
0,
"LATENT"
],
[
22,
23,
0,
21,
0,
"IMAGE"
],
[
23,
17,
0,
16,
2,
"CONDITIONING"
],
[
24,
2,
0,
16,
1,
"CONDITIONING"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 0.620921323059155,
"offset": [
161.65574993368958,
270.9522224395754
]
},
"workflowRendererVersion": "LG"
},
"version": 0.4
}
まとめ
今回は[ComfyUI]と[FLUX.1-dev]を使ってプロンプトから画像を生成するためのワークフローを作成する手順について紹介しました。
[ComfyUI]で[FLUX.1-dev]を動作させる必要最低限のノードと設定値でワークフローを作成してみました。
[ComfyUI]で[FLUX.1-dev]を動作させるワークフローを作りたい人の参考になれば幸いです。
スポンサーリンク
最後までご覧いただき、ありがとうございます。





