FLUX.3 Image Klein을 Diffusers에서 사용해 보기: Black Forest Labs의 최신 오픈 이미지 생성 모델
요약
Black Forest Labs가 오픈 소스로 FLUX.3 Image Klein 모델을 공개했습니다. 이 모델은 텍스트-투-이미지, 다중 참조 이미지-투-이미지 생성 및 바운딩 박스를 이용한 레이아웃 제어를 지원합니다. 특히 증류된 체크포인트는 빠른 추론 속도를 자랑하며, 모듈형 Diffusers 파이프라인으로 배포되어 유연성이 높습니다.
핵심 포인트
- FLUX.3 Image Klein은 텍스트-투-이미지 및 레이아웃 제어를 지원하는 오픈 모델입니다.
- 증류된 체크포인트는 H100에서 약 2초 만에 고화질 이미지를 생성할 수 있습니다.
- 모듈형 Diffusers 파이프라인으로 구성되어 사용자 정의가 용이합니다.
- LoRA 학습 스크립트와 다양한 사용 예시를 제공하여 활용도가 높습니다.
Welcome FLUX.3 Image Klein in Diffusers: Black Forest Labs의 최신 오픈 이미지 생성 모델
레이아웃 제어(layout control). 프롬프트에 바운딩 박스(bounding boxes)를 작성하여 이미지의 각 부분이 어디에 위치해야 하는지, 또는 참조 이미지의 어떤 부분을 이동시켜야 하는지를 지정할 수 있습니다.
두 개의 오픈 체크포인트 모두 FLUX.3 Image Klein 컬렉션에 포함되어 있습니다:
| Checkpoint | 설명 | 기본값 |
|---|---|---|
black-forest-labs/flux-3-image-klein | 시간 단계 증류(Time step distilled) 버전으로, 빠른 추론이 가능합니다. | 16 steps, CFG 없음 |
black-forest-labs/flux-3-image-klein-base | 기본 모델 (Base model) | 50 steps, CFG |
Hugging Face space로 이동하여 지금 바로 이미지를 생성해 보세요!
-
텍스트-투-이미지(text-to-image), 다중 참조 이미지-투-이미지(multi-reference image-to-image), 그리고 바운딩 박스 레이아웃 제어를 위한 단일 모델입니다.
-
증류된 체크포인트는 H100에서 약 2초 만에 1024 × 1024 이미지를 생성합니다. - 더 작은 GPU를 위해
from_single_file로 NVFP4 및 FP8 가중치를 로드할 수 있습니다. -
텍스트-투-이미지 및 이미지 편집을 위한 LoRA 학습 스크립트가 제공됩니다.
-
모듈형 Diffusers 파이프라인으로 배포되어, 블록을 제거하거나 자신만의 블록을 추가할 수 있습니다.
-
시작하기 (Getting started)
-
FLUX.3의 기능 (What FLUX.3 can do)
-
기본 모델 및 양자화 변형 (Base model and quantized variants)
-
LoRA 파인튜닝 (LoRA finetuning)
-
실행 비용 (What it costs to run)
-
아키텍처 (The architecture)
-
모듈형 Diffusers (Modular Diffusers)
-
사용해 보기 (Try it)
최신 diffusers와 transformers를 설치하세요.
(Qwen3-VL 텍스트 인코더용):
pip install -U diffusers transformers
증류된 체크포인트를 로드하고 이미지를 생성하는 방법:
import torch
from diffusers import ModularPipeline
pipe = ModularPipeline.from_pretrained(
프롬프트는 다음과 같습니다.
"황금 시간대에 눈 덮인 숲 공터에 경계하는 자세로 서 있는 빨간 여우의 광각 야생 사진. 여우가 프레임 중앙에 위치하며, 두꺼운 주황색 겨울 털이 신선한 흰 눈과 대비를 이룬다, 숨결..."
`image` 인수로 참조 이미지(또는 여러 개)를 전달합니다. 원하는 이미지의 캡션처럼 프롬프트를 작성하되, 변경 사항을 포함해야 합니다.
prompt = (
"같은 빨간 여우가 같은 눈 덮인 숲 공터에 있지만, 이제 보름달 아래 밤이다: 차가운 푸른 달빛, 깊은 그림자, 소나무 가지 사이로 보이는 별들, 빛을 반사하는 여우의 눈."
...
여러 참조 이미지를 사용할 경우, 프롬프트에서 `<ref_image_0>`, `<ref_image_1>`, ... 와 같이 순서대로 언급합니다. 이 순서는 `image`에 전달되는 순서를 따릅니다:
red_fox = pipe(prompt="빨간 여우", generator=torch.Generator().manual_seed(0), output="images")[0]
bench = pipe(prompt="나무 벤치", generator=torch.Generator().manual_seed(0), output="images")[0]
combined = pipe(
...
캡션 뒤에 JSON 리스트 형태로 영역을 추가합니다. 각 영역은 `id`, `bbox`, 그리고 `desc`를 가지며, 캡션에서 `<id>`로 언급됩니다.
박스는 `[y_min, x_min, y_max, x_max]` 형식으로 작성하며, y가 먼저 오고, 0–1000 스케일입니다. 스케일이 정규화되어 있기 때문에 같은 박스는 어떤 이미지 크기에서도 작동합니다.
layout_prompt = (
"단색의 생생한 연두색 배경 <background_1>을 중앙에 배치하고, 그 위에 검은 실루엣으로 된 사람 <silhouette_1>이 특징인 미니멀리스트 그래픽 일러스트레이션. 이 인물은 역동적인 중간 보폭 달리기 자세로 포착되어 있다..."
...
수정을 위해 각 영역은 그 내용이 어디에서 왔는지 (`src_bbox`, 참조 이미지의 경우)와 어디로 가는지 (`tgt_bbox`, 출력 이미지의 경우)를 명시합니다. 두 박스가 같은 영역에 있는 경우는 그대로 유지됩니다.
이 예시는 뜨개질한 기사(knitted knight)를 위쪽 왼쪽으로 이동시키고, 배경인 절벽, 바늘, 용, 그리고 불을 고정하는 방법입니다:
from diffusers.utils import load_image
knight_image = load_image("knight_orig.png")
edit_prompt = (
...
위의 모든 내용은 증류된(distilled) 체크포인트를 사용합니다. 기본(base) 체크포인트는 클래시파이어 프리 가이던스(classifier-free guidance)를 사용하여 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")
...
Black Forest Labs는 또한 트랜스포머를 단일 파일로 제공하며, 이는 `bf16` 형식과 두 가지 양자화(quantized) 형식인 `fp8r`(행별 FP8) 및 `nvfp4`로 제공됩니다. 이들 중 아무것이나 `from_single_file`을 사용하여 로드한 다음, 다른 구성 요소들은 이름으로 로드하여 bf16 트랜스포머가 너무 많이 다운로드되는 것을 방지할 수 있습니다.
from diffusers import BFLQuantizationConfig, Flux3Transformer2DModel, ModularPipeline
model_id = "black-forest-labs/flux-3-image-klein-base"
variant = "fp8r" # 또는 "nvfp4"
...
양자화되지 않은 단일 파일의 경우 `https://huggingface.co/{model_id}/blob/main/model.safetensors`를 사용하고, `quantization_config`는 생략합니다.
| Variant | Fast kernels on | Other GPUs |
|---|---|---|
`fp8r` | Compute capability 8.9+ (Ada, Hopper, Blackwell) | 가중치는 매 스텝마다 역양자화(dequantized)됩니다: 메모리 사용량은 적지만 속도 향상은 없습니다 |
`nvfp4` | Blackwell, `flashinfer-python` 및 `flashinfer-cubin`이 동일한 버전일 때 | 위와 동일 |
FLUX.3는 텍스트-투-이미지(text-to-image)와 이미지-투-이미지(image-to-image) 모두에 사용 가능하므로, 사용자 지정 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"
...
메모리 사용량을 줄이려면 몇 가지 최적화 플래그를 추가하십시오:
`--gradient_checkpointing --cache_latents --use_8bit_adam`
역방향 전파(backward pass)에서 활성화 값(activations)을 재계산합니다 (VRAM 사용량 감소, 약간 느려짐), `--cache_latents`
이미지를 사전 인코딩하고 VAE를 해제하며, `--use_8bit_adam`
옵티마이저 상태(optimizer states)를 8비트로 유지합니다.
실험해 볼 만한 몇 가지 설정값들이 있습니다. 아래 그리드는 서로 다른 LoRA 랭크와 옵티마이저로 동일한 타로 스타일을 학습시키며; 어댑터는 Hub의 `diffusers-modular/flux3-tarot-lora`에 있습니다.
더 많은 학습 기능과 구성은 DreamBooth FLUX.3 README에 문서화되어 있습니다.
지침 기반 편집(instruction-based editing)을 위해, 이미지-대-이미지 스크립트(`train_dreambooth_lora_flux3_klein_img2img.py`)
은 (참조 이미지, 대상 이미지, 지침) 삼중항(triplets)으로 학습하며, 여기서 참조 이미지는 프롬프트에서 `<ref_image_0>`로 지정됩니다.
모든 옵션과 전체 이미지-대-이미지 예시는 DreamBooth FLUX.3 README를 참고하십시오.
이 섹션에서는 모델의 메모리 사용량 및 생성 속도에 대해 이야기하겠습니다.
| name | peak allocated (after load) GiBs | peak allocated (after inference) GiBs |
|---|---|---|
| nvfp4 (RTX6000) | 13.4 | 15.3 |
| ... |
만약 메모리가 부족하다면:
- 양자화된 트랜스포머(quantized transformer)를 로드합니다.
- 텍스트 인코더(text encoder)를 별도로 실행하고 해제합니다. 이는 디노이징 전에 이미지당 한 번만 실행됩니다 (Encode once, generate many 참고).
- 자동 CPU 오프로딩(automatic CPU offloading)을 활성화하여 각 구성 요소를 실행하는 동안에만 GPU로 이동시킵니다 (저희가 벤치마크하지는 않았습니다)
from diffusers import ComponentsManager, ModularPipeline
manager = ComponentsManager()
manager.enable_auto_cpu_offload(device=
참조 이미지는 처리 시간을 약 두 배로 늘립니다. 참조 토큰은 생성되는 이미지와 텍스트가 포함된 동일한 시퀀스에 추가되므로, 1024 × 1024의 참조 이미지는 모든 트랜스포머 호출에 4,096개의 토큰을 추가합니다.
| 트랜스포머 호출당 토큰 스택: text-to-image 4,256개 토큰; image-to-image 8,272개; layout text-to-image 4,336개; layout image-to-image 8,800개 |
모델을 한 조각씩 열어보겠습니다. 이 모델은 세 가지 종류의 토큰을 사용합니다:
텍스트(text) - 생성되는 노이즈 이미지(noisy image) - 그리고 선택적인 참조 이미지(reference images)
FLUX.3는 이미지를 위한 잠재 공간 흐름 모델(latent-space flow model)입니다. 이는 디노이저가 잠재값(latents)을 입력으로 받아 잠재값을 출력한다는 것을 의미합니다. 우리는 VAE를 사용하여 이 잠재값을 픽셀로 디코딩합니다. FLUX.3는 Flux.2와 동일한 VAE 아키텍처를 사용합니다.
FLUX.2의 VAE는 이미지를 각 방향으로 8배 압축하여 32 채널로 만들고, 그 잠재값의 모든 2 × 2 패치를 128 채널을 가진 단일 토큰에 패킹(packing)합니다.
따라서 하나의 토큰은 16 × 16 픽셀 패치를 커버하며, 1024 × 1024 이미지는 4,096개의 토큰으로 이루어진 64 × 64 그리드가 됩니다. 노이즈 이미지는 정확히 그 모양의 무작위 노이즈로 시작합니다. 참조 이미지는 동일한 VAE 인코더와 패킹 과정을 거치며 자체 크기를 유지합니다.
텍스트 인코더는 비전-언어 모델(vision-language model)인 Qwen3-VL입니다. FLUX.3는 마지막 레이어만 사용하는 것이 아니라, 36개 레이어 중 8개의 히든 스테이트(레이어 4, 8, …, 32)를 읽어 스택하고, 따라서 각 텍스트 토큰은 선형 레이어를 통해 트랜스포머의 너비인 3072로 투영되기 전에 8 × 2560 = 20,480 차원의 벡터가 됩니다.
이는 단순히 최종 레이어뿐만 아니라 언어 모델의 여러 깊이에서 온 트랜스포머 특징을 제공합니다. 프롬프트는 80 토큰의 배수로 패딩되며, 트랜스포머는 이 패딩에도 어텐션(attend)하기 때문에 파이프라인은 호출당 하나의 프롬프트를 사용합니다.
트랜스포머는 두 단계에 걸쳐 토큰을 처리합니다:
스테이지 1: 개별 모드 블록(per-mode blocks). 각 스트림은 자체 가중치를 가진 5개의 블록을 거칩니다. 텍스트는 자체 블록을 가지고, 노이즈 이미지도 자체 블록을 가지며, 참조 이미지는 자체 블록을 가집니다.스테이지 2: 결합 블록(joint blocks). 이 스트림들은 하나의 시퀀스로 연결되어 [텍스트 | 이미지 | 참조]가 되며, 이는 한 세트의 가중치를 공유하는 28개의 블록을 거칩니다. 두 스테이지는 누가 누구에게 주의를 기울일 수 있는지에서 차이가 납니다. 스테이지 1에서는 각 스트림이 자신에게만 주의를 기울이므로, 각 종류의 토큰이 먼저 자체적인 조건에서 정제됩니다. 반면, 스테이지 2에서는 모든 것이 모든 것에 주의를 기울이며, 이미지가 텍스트와 참조로부터 학습합니다. 비교하자면, FLUX.2의 더블 스트림 블록 역시 텍스트와 이미지에 별도의 가중치를 부여하지만, 처음부터 서로에게 주의를 기울이도록 합니다. FLUX.3는 먼저 스트림들을 완전히 분리한 다음 병합합니다. 마지막에는 텍스트 및 참조 토큰은 단순히 제거됩니다. 오직 이미지 토큰만이 출력 레이어를 거치며, 이는 이들을 깨끗한 이미지 쪽으로 한 단계 이동시키는 방법을 예측합니다. 어느 스테이지의 블록이든 모든 블록은 동일한 형태를 가집니다. 어텐션(Attention)과 MLP는 동일하게 정규화된 입력에 병렬로 실행되며, 그 합이 잔차 스트림(residual stream)에 다시 더해집니다. 각 블록은 자체적으로 학습되는 스케일이나 시프트가 없는 LayerNorm으로 시작합니다. 스케일, 시프트, 게이트는 대신 타임스텝 임베딩(timestep embedding)에서 가져옵니다 (이것을 *변조(modulation)*라고 합니다). 어텐션 내부에서는 쿼리(query)와 키(key)가 RMS-정규화되고 회전 위치 임베딩(RoPE, rotary position embeddings)을 얻으며, 이는 아래에서 살펴보겠습니다. 결합 블록에서는 모든 토큰이 동일한 가중치를 공유하지만, 텍스트, 이미지, 참조 토큰 각각은 자체적인 스케일, 시프트, 게이트를 갖습니다. def block(x, shift, scale, gate): # shift, scale, gate는 토큰의 타임스텝 임베딩에서 가져옴 h = layer_norm(x) # 학습되는 스케일이나 시프트 없음 h = (1 + scale) * h + shift ... FLUX.1과 FLUX.2에서는 하나의 타임스텝 임베딩이 모든 토큰을 변조합니다. FLUX.3에서는 변조가 토큰의 종류에 따라 달라집니다. 노이즈 이미지 토큰은 현재 타임스텝 t에 의해 변조됩니다.
텍스트 및 참조 토큰은 항상 타임스텝 0에 의해 변조됩니다. 이는 '깨끗하며, 디노이즈할 것이 없다'는 의미입니다. 따라서 출력과 거의 동일해 보이는 참조가 주어지는 컨텍스트로 표시될 뿐, 생성해야 할 무언가로 간주되지 않습니다.
지식 증류된 체크포인트는 *흐름 맵(flow map)*입니다. 또한 각 스텝이 점프할 타임스텝도 알려줍니다. 이 두 번째 타임스텝은 자체 임베딩을 얻으며, 이는 모든 토큰의 변조에 추가되어 각 16개 스텝이 더 큰 점프를 할 수 있게 합니다.
어텐션(Attention) 자체는 토큰의 위치를 알지 못합니다 (이 현상을 순열 등변성(permutation equivariance)이라고 합니다). RoPE는 각 쿼리(query)와 키(key)를 토큰의 위치에 따라 달라지는 양만큼 회전시켜 이를 수정합니다. FLUX.3은 네 개의 위치 축, 즉 (t, h, w, l) (타임스텝, 높이, 너비, 시퀀스 길이)을 사용하며, 각 축에 128차원 어텐션 헤드 각각의 4분의 1(32차원)을 할당합니다:
AI 자동 생성 콘텐츠
본 콘텐츠는 Hugging Face Blog의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기