跳到正文
Hugging Face Blog·· 17 小時前精選AI 評分72

FLUX.3 Image Klein 登陸 Diffusers,提供兩款開放檢查點

Welcome FLUX.3 Image Klein in Diffusers

AI 導讀

FLUX.3 Image Klein 現已支援 Diffusers,可用於文生圖、多參考圖圖生圖及邊界框版面控制。兩款開放檢查點分別是預設以 16 步生成且不使用 CFG 的蒸餾版,以及使用 50 步和 CFG 的 base 版。蒸餾版生成 1024 × 1024 圖像,在單張 NVIDIA H100 80GB 上平均耗時 1.93 s;文章亦提供 LoRA 微調腳本及量化權重載入方法。

推薦理由

文章展示了以邊界框安排生成版面及移動參考圖區域的做法,並附上 Diffusers 範例與 LoRA 微調腳本。

正文 · 繁體中文

Black Forest Labs 的 FLUX.3 Image Klein 現已推出,推出首日起即可在 Diffusers 中運行。這個模型支援文生圖和多參考圖圖生圖,並新增了版面配置控制功能。你可以在提示詞中寫入邊界框,指定圖片各部分的位置,或指定要移動參考圖片中的哪些部分。

兩個開放檢查點均收錄於FLUX.3 Image Klein 系列:

檢查點 説明 預設設定
black-forest-labs/flux-3-image-klein 經時間步蒸餾,適合快速推理 16 步,不使用 CFG
black-forest-labs/flux-3-image-klein-base 基礎模型 50 步,使用 CFG

a red fox in a snowy forest (text-to-image), the same fox re-rendered from that image (image-to-image), a black stippled running silhouette on a chartreuse background, drawn inside its labeled bounding box, and a knitted knight moved from a "from" box to a "to" box next to a knitted dragon (layout editing)

你現在就可以前往 Hugging Face Space 生成圖片!

重點摘要

  • 一個模型支援文生圖、多參考圖圖生圖,以及邊界框版面配置控制。
  • 蒸餾檢查點預設約 2 秒即可在 H100 上生成 1024 × 1024 圖片。
  • NVFP4 和 FP8 權重可透過 from_single_file 載入,適用於較低階的 GPU。
  • 提供用於文生圖和圖片編輯的 LoRA 訓練腳本。
  • 以 Modular Diffusers 管線形式提供,你可以抽出模組或加入自訂模組。

目錄

開始使用

安裝最新版本的 diffusers 和 transformers(用於 Qwen3-VL 文字編碼器):

pip install -U diffusers transformers

載入蒸餾檢查點並生成圖片:

import torch
from diffusers import ModularPipeline

pipe = ModularPipeline.from_pretrained("black-forest-labs/flux-3-image-klein")
pipe.load_components(dtype=torch.bfloat16)
pipe.to("cuda")

pipe(prompt="a red fox", output="images")[0].save("fox.png")

FLUX.3 的功能

文生圖

FLUX.3 對包含主體、場景、光線、構圖和風格的完整場景描述效果最佳。Black Forest Labs 的官方提示詞指南提供更多建議。蒸餾檢查點預設會生成 1024 × 1024 圖片,並執行 16 步。傳入 height、width 或 num_inference_steps 即可更改相關設定。

prompt = (
    "A wide-angle wildlife photograph of a red fox standing alert in a snow-covered forest clearing at golden hour. "
    "The fox is centered in the frame, its thick orange winter coat contrasting with the fresh white snow, breath "
    "visible in the cold air. Snow-laden pine trees fill the softly blurred background, and low warm sunlight rakes "
    "across the scene from the left, casting long blue shadows."
)

fox = pipe(
    prompt=prompt,
    generator=torch.Generator().manual_seed(0),
    output="images"
)[0]
fox.save("fox.png")
A red fox standing alert in a snow-covered forest clearing, lit by low golden sunlight from the left
文生圖

圖生圖

使用 image 參數傳入一張或多張參考圖片。提示詞應描述你想要的圖片,並寫明所需變更。

prompt = (
    "The same red fox in the same snow-covered forest clearing, now at night under a full moon: cool blue "
    "moonlight, deep shadows, stars visible through the pine branches, the fox's eyes catching the light."
)
night = pipe(
    prompt=prompt,
    image=fox, # from the previous text to image example
    generator=torch.Generator().manual_seed(0),
    output="images",
)[0]
night.save("night.png")
The fox from the previous image, relit in cold blue light
圖生圖

傳入多張參考圖片時,請按傳入 image 的順序,在提示詞中以 <ref_image_0>、<ref_image_1>……指稱它們:

red_fox = pipe(prompt="a red fox", generator=torch.Generator().manual_seed(0), output="images")[0]
bench = pipe(prompt="a wooden bench", generator=torch.Generator().manual_seed(0), output="images")[0]

combined = pipe(
    prompt="The fox from <ref_image_0> sitting on the wooden bench from <ref_image_1> in a snowy setting.",
    image=[red_fox, bench],
    output="images",
)[0]

combined.save("combined.png")
A red fox sitting on dry grass A slatted wooden bench against a plain grey wall The same fox sitting on the same bench, with snow on the ground
<ref_image_0>:一隻紅狐 <ref_image_1>:一張木製長椅 長椅上的狐狸

版面配置控制

在説明文字後加入區域的 JSON 清單。每個區域包含 id、bbox 和 desc,並在説明文字中以 <id> 提及。

邊界框格式為 [y_min, x_min, y_max, x_max],先寫 y 座標,範圍為 0–1000。由於採用標準化尺度,同一個邊界框適用於任何圖片尺寸。

在新圖片中放置區域

layout_prompt = (
    "Minimalist graphic illustration featuring a black silhouette of a person <silhouette_1> centered against a "
    "solid, vibrant chartreuse background <background_1>. The figure is captured in a dynamic, mid-stride running "
    "pose, facing toward the left side of the frame. "
    '[{"id": "background_1", "bbox": [0, 0, 1000, 1000], "desc": "A flat field of neon yellow-green with a subtle '
    'paper texture and fine, organic grain."}, {"id": "silhouette_1", "bbox": [150, 150, 850, 850], "desc": "A '
    "black silhouette of a person in motion, made of dense stippled ink. The leading edges are solid; the trailing "
    'arm and leg dissolve into coarse square pixels and scattered dots."}]'
)

runner = pipe(prompt=layout_prompt, generator=torch.Generator().manual_seed(0), output="images")[0]
Diagram: the caption and the two region descriptions on the left, the two boxes on a 0–1000 grid in the middle, and the generated image on the right, where a black stippled runner fills the silhouette box on a chartreuse background
每個區域的 desc 都會繪製在其 bbox 內

在參考圖片中移動區域

編輯圖片時,每個區域會指定其內容的來源位置(參考圖片中的 src_bbox)和目的地(輸出圖片中的 tgt_bbox)。如果兩個邊界框相同,該區域便會保持原位。

這個例子會將編織騎士向上、向左移動,並固定背景、懸崖、針、龍和火焰的位置:

from diffusers.utils import load_image

knight_image = load_image("knight_orig.png")
edit_prompt = (
    "In <ref_image_0>, move the miniature grey amigurumi knight figure <knight_1> upwards and to the left along the "
    "yarn cliff <cliff_1>. Keep the rest of the image completely unchanged, preserving the blurred yarn backdrop "
    "<backdrop_1>, the large knitted dragon <dragon_1>, and the fiery orange thread <fire_1>. "
    '[{"id": "knight_1", "from": "ref_image_0", "src_bbox": [500, 150, 850, 350], "tgt_bbox": [194, 55, 544, 255], '
    '"desc": "A miniature amigurumi knight crocheted from thick grey woolen yarn."}, '
    '{"id": "backdrop_1", "from": "ref_image_0", "src_bbox": [0, 0, 1000, 1000], "tgt_bbox": [0, 0, 1000, 1000], '
    '"desc": "A soft, out-of-focus backdrop of cream and indigo knitted yarn."}, '
    '{"id": "cliff_1", "from": "ref_image_0", "src_bbox": [300, 0, 1000, 450], "tgt_bbox": [300, 0, 1000, 450], '
    '"desc": "A steep cliff of stacked yarn skeins in mustard, terracotta, and indigo."}, '
    '{"id": "needle_1", "from": "ref_image_0", "src_bbox": [420, 250, 550, 450], "tgt_bbox": [420, 250, 550, 450], '
    '"desc": "An oversized polished steel tapestry needle."}, '
    '{"id": "dragon_1", "from": "ref_image_0", "src_bbox": [100, 600, 950, 1000], "tgt_bbox": [100, 600, 950, 1000], '
    '"desc": "A large, fluffy knitted dragon in terracotta and mustard yarn."}, '
    '{"id": "fire_1", "from": "ref_image_0", "src_bbox": [350, 400, 650, 650], "tgt_bbox": [350, 400, 650, 650], '
    '"desc": "Curled puffs of fiery orange angora thread suspended in mid-air."}]'
)

moved = pipe(prompt=edit_prompt, image=knight_image, generator=torch.Generator().manual_seed(0), output="images")[0]
Left: the reference with the knight's source box. Right: the output with an arrow from the source box to the target box; the pinned regions are outlined in white
騎士會從 src_bbox 移至 tgt_bbox,場景其餘部分則保持原位

基礎模型與量化變體

基礎模型

以上內容均使用蒸餾檢查點。基礎檢查點會以分類器自由引導執行 50 步,也是用於微調的檢查點(參閲 LoRA 微調)。

pipe = ModularPipeline.from_pretrained("black-forest-labs/flux-3-image-klein-base")
pipe.load_components(dtype={"vae": torch.float32, "default": torch.bfloat16})
pipe.to("cuda")

pipe.guider = pipe.guider.new(guidance_scale=5.0)  # optional
image = pipe(prompt=prompt, output="images")[0]

單檔格式檢查點

Black Forest Labs 亦提供單一檔案形式的 transformer,包括 bf16 及兩種量化格式:fp8r(逐行 FP8)和 nvfp4。使用 from_single_file 載入其中任何一種,然後按名稱載入其他元件,避免同時下載 bf16 transformer。

from diffusers import BFLQuantizationConfig, Flux3Transformer2DModel, ModularPipeline

model_id = "black-forest-labs/flux-3-image-klein-base"
variant = "fp8r"  # or "nvfp4"

transformer = Flux3Transformer2DModel.from_single_file(
    f"https://huggingface.co/{model_id}/blob/main/variants/{variant}/model.safetensors",
    config=model_id,
    subfolder="transformer",
    quantization_config=BFLQuantizationConfig(compute_dtype=torch.bfloat16),
    dtype=torch.bfloat16,
)

pipe = ModularPipeline.from_pretrained(model_id)
pipe.load_components(dtype=torch.bfloat16)
pipe.update_components(transformer=transformer)
pipe.to("cuda")

對於未量化的單一檔案,使用 https://huggingface.co/{model_id}/blob/main/model.safetensors,並移除 quantization_config。

變體 快速核心適用的 GPU 其他 GPU
fp8r 計算能力 8.9+(Ada、Hopper、Blackwell) 每一步都會對權重進行反量化:記憶體用量較低,但速度不會提升
nvfp4 Blackwell,flashinfer-python 和 flashinfer-cubin 的版本須一致 同上

LoRA 微調

FLUX.3 同時適用於文字生成圖片和圖片生成圖片,因此是自訂 LoRA 的理想基礎。diffusers 提供適用於這兩種任務的 DreamBooth LoRA 訓練指令碼(你也可以使用 Ostris' AI Toolkit 進行訓練)。

以下是文字生成圖片的範例:使用 multimodalart/1920-raider-waite-tarot-public-domain 數據集學習塔羅牌風格,並以 trtcrd 作為觸發詞:

accelerate launch train_dreambooth_lora_flux3_klein.py \
  --pretrained_model_name_or_path="black-forest-labs/flux-3-image-klein-base" \
  --dataset_name="multimodalart/1920-raider-waite-tarot-public-domain" \
  --caption_column="caption" \
  --instance_prompt="trtcrd" \
  --output_dir="trained-flux3-tarot-lora" \
  --mixed_precision="bf16" \
  --resolution=1024 \
  --use_aspect_ratio_buckets \
  --train_batch_size=1 \
  --rank=16 \
  --lora_alpha=16 \
  --learning_rate=1e-4 \
  --lr_scheduler="constant" \
  --max_train_steps=1500 \
  --validation_prompt="a trtcrd of a cat, tarot style" \
  --validation_epochs=25 \
  --seed=0 \
  --push_to_hub

如要減少記憶體用量,可加入幾個最佳化旗標:

  --gradient_checkpointing \
  --cache_latents \
  --use_8bit_adam

--gradient_checkpointing 會在反向傳播時重新計算活化值(減少 VRAM 用量,但速度稍慢),--cache_latents 會預先編碼圖片並釋放 VAE,而 --use_8bit_adam 會將最佳化器狀態維持在 8-bit。

有幾個參數值得試試。下方網格展示使用不同 LoRA rank 和最佳化器訓練相同塔羅牌風格的結果;這些適配器已上載至 diffusers-modular/flux3-tarot-lora。更多訓練功能和設定詳見 DreamBooth FLUX.3 README。

FLUX.3 tarot-style LoRA across ranks and optimizers: the base model with no LoRA, then rank 16, rank 8 and rank 32 (AdamW, lr 1e-4) and a Prodigy run, on two held-out prompts

如要進行以指令為基礎的編輯,圖片生成圖片指令碼(train_dreambooth_lora_flux3_klein_img2img.py)會使用(參考圖片、目標圖片、指令)三元組進行訓練,並在提示詞中以 <ref_image_0> 指向參考圖片。

所有選項及完整的圖片生成圖片範例,請參閲 DreamBooth FLUX.3 README。

執行成本

本節將討論模型的記憶體用量及生成速度。

記憶體

名稱 峯值記憶體配置量(載入後)GiBs 峯值記憶體配置量(推理後)GiBs
nvfp4 (RTX6000) 13.4 15.3
fp8r (H100) 14.35 16.27
bf16 (H100) 18.80 20.72

如果可用記憶體較少:

  • 載入量化版 transformer。
  • 將文字編碼器獨立執行,然後釋放其資源。它每張圖片只會執行一次,並在去噪前完成(參見 編碼一次,生成多張)。
  • 啟用自動 CPU 卸載,讓每個元件只在執行期間移至 GPU(我們沒有對此進行基準測試)
from diffusers import ComponentsManager, ModularPipeline

manager = ComponentsManager()
manager.enable_auto_cpu_offload(device="cuda")

pipe = ModularPipeline.from_pretrained("black-forest-labs/flux-3-image-klein", components_manager=manager)
pipe.load_components(dtype={"vae": torch.float32, "default": torch.bfloat16})
# no pipe.to("cuda"): the manager handles device placement

速度

蒸餾版模型檢查點(16 步)的端到端執行時間:預熱後執行三次並取平均值:

工作流程 輸出尺寸 時間 峯值記憶體
文字轉圖片 1024 × 1024 1.93 s 23.8 GiB
圖片轉圖片,使用一張 1024 × 1024 參考圖片 1024 × 1024 3.87 s 23.8 GiB
版面編輯(騎士),使用一張 1360 × 768 參考圖片 1360 × 768 4.10 s 23.8 GiB

單張 NVIDIA H100 80GB,未使用卸載,採用預設注意力後端。

參考圖片會令所需時間大約變成兩倍。參考圖片的 token 會與文字及正在生成的圖片一同加入同一序列,因此一張 1024 × 1024 的參考圖片會令每次 Transformer 呼叫增加 4,096 個 token

Stacked bars of tokens per transformer call: text-to-image 4,256 tokens; image-to-image 8,272; layout text-to-image 4,336; layout image-to-image 8,800
每次 Transformer 呼叫的 token 數量堆疊長條圖:文字轉圖片 4,256 個 token;圖片轉圖片 8,272 個 token;版面文字轉圖片 4,336 個 token;版面圖片轉圖片 8,800 個 token

架構

讓我們逐一拆解模型的各個部分。模型會接收三類 token:

  1. 文字
  2. 正在生成的含雜訊圖像
  3. 以及可選的參考圖片

從像素到 token

FLUX.3 是一種用於圖像生成的潛在空間流模型。這表示去噪器以潛在表示作為輸入,並輸出潛在表示。我們使用 VAE 將潛在表示解碼回像素。FLUX.3 使用與 Flux.2 相同的 VAE 架構。

FLUX.2 VAE 會將圖像在每個方向壓縮 8×,轉換為 32 個通道;然後將該潛在表示中的每個 2 × 2 區塊打包成一個含 128 個通道的 token。

因此,一個 token 覆蓋 16 × 16 像素的區塊,而一張 1024 × 1024 圖像會變成由 4,096 個 token 組成的 64 × 64 網格。含噪圖像一開始是形狀完全相同的隨機雜訊。參考圖像會經過相同的 VAE 編碼器及打包程序,並保留自身尺寸。

從提示詞到 token

文字編碼器是 Qwen3-VL,一種視覺語言模型。FLUX.3 並非只使用它的最後一層,而是讀取其 36 層中的 八 層隱藏狀態(第 4、8、…、32 層)並將它們堆疊,因此每個文字 token 在經過線性層投影至 Transformer 的 3072 維寬度之前,會變成一個 8 × 2560 = 20,480 維向量。

這讓 Transformer 能取得來自語言模型多個深度的特徵,而不只是最後一層。提示詞會填充至 80 個 token 的倍數,而 Transformer 也會對填充內容進行注意力運算,這就是整個流程每次呼叫只接受一個提示詞的原因。

兩個階段

Transformer 分兩個階段處理 token:

  1. 階段 1:各模式區塊。 每個串流會經過 5 個使用各自權重的區塊。文字有自己的區塊,含噪圖像有自己的區塊,參考圖像也有自己的區塊。
  2. 階段 2:聯合區塊。 各串流會串接成一個序列 [text | image | reference],再經過 28 個共用同一組權重的區塊。

兩個階段的差異在於哪些內容可以互相注意。

在階段 1 中,每個串流只會注意自身,因此各類 token 會先按各自的方式進行細化。在階段 2 中,所有內容都會互相注意,圖像因而能從文字和參考圖像中學習。相比之下,FLUX.2 的雙串流區塊同樣為文字和圖像使用不同權重,但從一開始就允許它們互相注意。FLUX.3 則先讓各串流完全分開,之後才將它們合併。

最後,文字 token 和參考圖像 token 會直接丟棄。只有圖像 token 會經過輸出層,由輸出層預測如何將它們移動一步,使其更接近乾淨圖像。

區塊內部

無論屬於哪個階段,每個區塊的結構都相同。注意力和 MLP 會在同一個正規化輸入上並行運算,兩者的輸出相加後再加回殘差流。

每個區塊都會先經過一個 LayerNorm,而它本身沒有可學習的縮放或平移參數。縮放、平移和閘控則來自時間步嵌入(這稱為調制)。在注意力模組內,查詢和鍵會經過 RMS 正規化,並加入旋轉位置嵌入(RoPE),我們會在下文探討。

在聯合區塊中,所有 token 共用相同權重,但文字、圖像和參考圖像 token 各自有自己的縮放、平移和閘控。

def block(x, shift, scale, gate):      # shift, scale, gate come from the token's timestep embedding
    h = layer_norm(x)                  # no learned scale or shift
    h = (1 + scale) * h + shift
    q, k, v = to_q(h), to_k(h), to_v(h)
    q, k = rope(rms_norm(q)), rope(rms_norm(k))
    out = attention(q, k, v) + mlp(h)  # parallel, MLP is SwiGLU
    return x + gate * out

每個 token 都有自己的時間步

在 FLUX.1 和 FLUX.2 中,一個時間步嵌入會調制所有 token。在 FLUX.3 中,調制方式則取決於 token 的類型。

雜訊圖像 token 會由當前時間步 t 調制。文字和參考 token 則一律由時間步 0 調制,意思是「乾淨,這裏毋須去噪」。因此,即使參考圖看起來幾乎與輸出相同,模型仍會將它標記為提供的上下文,而不是需要生成的內容。

蒸餾後的檢查點是一個流映射。模型也會獲知每一步要跳到的時間步。第二個時間步有自己的嵌入向量,並會加入每個 token 的調制中,因此 16 個步驟中的每一步都可以跳得更遠。

四個維度的位置

注意力本身並不知道 token 所在的位置(這種現象稱為置換等變性)。RoPE 會根據 token 的位置旋轉每個 query 和 key,從而解決這個問題。FLUX.3 使用四條位置軸 (t, h, w, l)(時間步、高度、寬度、序列長度),並為每個 128 維注意力頭的每條軸分配四分之一(32 個維度):

Token t:時間步 h:高度 w:寬度 l:序列長度
文字 token i 0 0 0 i
位於 (row, col) 的圖像 token 0 row / 2 col / 2 0
位於 (row, col) 的參考 k 0 row / 2 col / 2 −(k + 1)

文字 token 沿著 l 排列,就像句子中的詞語。圖像和參考圖是在 (h, w) 中的 2D 網格,並沿著 l 彼此分隔。由於參考圖使用與輸出相同的 (h, w) 座標,「參考圖中的相同位置」對模型而言有明確的含義,src_bbox / tgt_bbox 編輯正是依賴這一點。

去噪迴圈

FLUX.3 是一種流匹配模型。生成從純雜訊開始,在 50 個步驟中的每一步,transformer 都會預測一個速度。這是從雜訊走向乾淨圖像的方向。排程器會沿著這個方向前進一步。

在每一步,你也可以讀取模型目前對最終圖像的猜測。在幾個步驟解碼這個猜測,就能看到圖像如何逐漸成形:

step01 step05 step10 step15 step25 step50
第 1 步 第 5 步 第 10 步 第 15 步 第 25 步 第 50 步

到第 10 步時,狐狸、牠的姿勢和光線已經成形,而雜訊水平仍為 0.97。覆雪的樹枝和毛皮的質感則只會在最後幾個步驟中出現。FLUX.3 的排程器使用較大的時間偏移(6.93),令整個生成過程的大部分時間都維持較高的雜訊水平:50 個步驟中有 44 步的 σ 高於 0.5。我們在 pipeline 中加入一個小型區塊來製作這張圖,這也帶我們來到 Modular Diffusers。

如果你剛接觸流匹配,我們準備了適合初學者的教學和影片,讓你瞭解它的運作方式。

Modular Diffusers

FLUX.3 以 Modular Diffusers pipeline 形式提供。

查看工作流程

你可以列出工作流程,並列印每個工作流程的確切區塊,而毋須載入任何權重。

from diffusers import Flux3AutoBlocks

blocks = Flux3AutoBlocks()
print(blocks.available_workflows)
# ['text2image', 'image_conditioned']

print(list(blocks.get_workflow("text2image").sub_blocks))
# ['text_encoder', 'denoise.input', 'denoise.prepare_latents', 'denoise.set_timesteps',
#  'denoise.prepare_rope_inputs', 'denoise.denoise', 'denoise.after_denoise', 'decode']

get_workflow() 會解析自動分支,並提供即將執行的簡明步驟序列。print(blocks.get_workflow("image_conditioned").doc) 會列印該工作流程的元件、輸入、預設值和輸出。

編碼一次,生成多次

將文字編碼器移出,對提示詞編碼一次,釋放它,再使用快取的嵌入向量生成內容。

import torch
from diffusers import ModularPipeline

model_id = "black-forest-labs/flux-3-image-klein-base"

blocks = ModularPipeline.from_pretrained(model_id).blocks
text_blocks = blocks.sub_blocks.pop("text_encoder")  # `blocks` now starts at the VAE encoder

text_pipe = text_blocks.init_pipeline(model_id)
text_pipe.load_components(dtype=torch.bfloat16)
text_pipe.to("cuda")

state = text_pipe(prompt=prompt, negative_prompt="")  # no guider here, so ask for the negative embeddings

prompt_embeds = state.get("prompt_embeds")
negative_prompt_embeds = state.get("negative_prompt_embeds")

del text_pipe
torch.cuda.empty_cache()

image_pipe = blocks.init_pipeline(model_id)  # no text encoder to load
image_pipe.load_components(dtype={"vae": torch.float32, "default": torch.bfloat16})
image_pipe.to("cuda")

for seed in range(3):
    image = image_pipe(
        prompt_embeds=prompt_embeds,
        negative_prompt_embeds=negative_prompt_embeds,
        generator=torch.Generator().manual_seed(seed),
        output="images",
    )[0]
    image.save(f"{seed}.png")

在迴圈中加入一步

上方的去噪圖是透過加入一個額外區塊製作的;這個區塊會記錄模型在每一步對乾淨圖像的猜測:

from diffusers.modular_pipelines import Flux3AutoBlocks, InputParam, ModularPipelineBlocks, OutputParam


class Flux3PreviewStep(ModularPipelineBlocks):
    model_name = "flux3"

    @property
    def inputs(self):
        return [InputParam("latents"), InputParam("noise_pred")]

    @property
    def intermediate_outputs(self):
        return [OutputParam("x0_previews", type_hint=list)]

    @torch.no_grad()
    def __call__(self, components, block_state, i, t):
        if i == 0:
            block_state.x0_previews = []
        sigma = t / 1000  # timesteps are sigmas scaled to [0, 1000]
        block_state.x0_previews.append(block_state.latents - sigma * block_state.noise_pred)  # x0 = x_t - sigma * v
        return components, block_state


blocks = Flux3AutoBlocks()
denoise_loop = blocks.sub_blocks["denoise"].sub_blocks["text2image"].sub_blocks["denoise"]
denoise_loop.sub_blocks.insert("preview", Flux3PreviewStep(), 1)  # between "denoiser" and "after_denoiser"

pipe = blocks.init_pipeline(model_id)
pipe.load_components(dtype={"vae": torch.float32, "default": torch.bfloat16})
pipe.to("cuda")

out = pipe(prompt=prompt, generator=torch.Generator().manual_seed(0), output=["x0_previews", "images"])

試用

用 FLUX.3 做了甚麼?歡迎在 Hub 分享你的 LoRA 和工作流程。我們很想看看!😎

來源:Hugging Face Blog · huggingface.co