FLUX.3 Image Klein의 다중 참조 편집과 레이아웃 제어

이미지 생성 모델의 데모는 대개 한 문장과 한 장의 결과로 끝난다. 실제 제품에서는 그 다음 요청부터 일이 어려워진다. 사용자는 첫 이미지의 인물은 유지하고, 두 번째 이미지의 가방을 가져오고, 로고는 오른쪽 위에 두며, 나머지 배경은 건드리지 말라고 요구한다. 이때는 한 번의 미려한 샘플보다 수정 지시가 반복되어도 대상, 위치, 정체성이 얼마나 안정적으로 유지되는지가 중요하다.

Hugging Face는 2026년 10월 15일 Black Forest Labs의 FLUX.3 Image Klein을 Diffusers에서 당일 지원한다고 발표했다.[1] 발표된 distilled checkpoint는 text-to-image, 최대 10장 참조를 쓰는 image-to-image, bounding-box 레이아웃 제어를 하나의 모델에서 처리한다. 기본값은 1,024×1,024 출력, 16 inference step, classifier-free guidance 없음이다. 별도의 Base checkpoint는 기본 50 step과 CFG 3.5를 사용하며 학습과 연구에 맞춰져 있다.

좌표를 적었다고 픽셀이 고정되는 것은 아니다. 여러 참조를 넣었다고 대상 정체성이 자동으로 보존되는 것도 아니다. FLUX.3 Image Klein을 평가할 때는 생성 품질과 함께 좌표 준수율, 비편집 영역 보존, 참조 간 속성 혼합, prompt upsampler 비용, 양자화별 실패율을 같은 실험에서 측정해야 한다.

공개된 자산의 정확한 경계

모델 카드에서 Klein은 image transformer 기준 5.6B 파라미터의 공개 가중치 모델로 설명된다.[2] 이 숫자에는 Qwen3-VL-4B-Instruct text encoder가 포함되지 않는다. Image autoencoder도 별도 구성 요소다. 따라서 “5.6B니까 5.6B 모델 하나의 메모리만 계산하면 된다”는 산정은 틀릴 수 있다.

Distilled 저장소에는 BF16 transformer와 FP8·NVFP4 variant가 함께 제공된다. Text encoder와 autoencoder도 패키지에 들어간다. Prompt upsampler는 짧은 사용자 요청을 모델이 학습한 형태의 긴 장면 설명으로 확장한다. Model card는 upsampler 없이 짧은 prompt를 그대로 보내면 결과가 일반적이고 약해질 수 있다고 경고한다.

Reference inference code는 별도 GitHub 저장소에 공개되어 있다.[3] 이 코드는 Python API, CLI, prompt upsampler, layout JSON 처리와 양자화 실행 경로를 제공한다. 코드 저장소의 라이선스 표시는 Apache-2.0이다. 그러나 모델 가중치는 FLUX Kommunity License를 따른다. 코드가 오픈소스라는 사실을 근거로 가중치까지 Apache-2.0이라고 부르면 안 된다.

FLUX Kommunity License는 비상업·비프로덕션 이용과 일정 조건을 충족하는 Qualifying User의 상업적 output 이용을 구분한다.[2] Model card는 상업적 output 예외가 라이선스 조건에 종속된다고 명시한다. 조직 매출, production 사용, 파생 모델, content filtering 의무는 실제 라이선스 원문과 법무 검토를 거쳐야 한다. 이 글은 법률 자문이 아니다.

“공개 가중치”와 “오픈소스”도 분리해야 한다. 사용자는 weight를 내려받아 self-hosting할 수 있다. 하지만 weight 사용권은 OSI 라이선스가 아니라 커스텀 라이선스로 제한된다. 반면 reference code와 prompt upsampler에는 별도 라이선스가 적용될 수 있다. 배포 기록에는 각 artifact의 이름, revision, digest, 라이선스를 따로 남기는 편이 안전하다.

기능의 핵심은 하나의 모델보다 하나의 조건 문법이다

Text-to-image 경로는 자세한 장면 caption을 입력으로 받는다. Single-reference edit는 원본 이미지를 넣고 바뀐 최종 장면을 caption으로 설명한다. Multi-reference composition은 prompt에서 참조를 <ref_image_0>, <ref_image_1> 순서로 지칭한다. 참조 배열의 순서를 바꾸면 같은 텍스트라도 의미가 달라질 수 있다.[1]

레이아웃 제어는 caption 뒤에 JSON region 목록을 붙이는 방식이다. 각 region은 id, bbox, desc를 가진다. bbox 순서는 흔히 예상하는 x 우선이 아니라 [y_min, x_min, y_max, x_max]다. 다만 실행 경로마다 좌표 단위가 다르다. Diffusers와 모델 카드의 inline prompt는 0부터 1000까지의 정수 grid를 쓰지만, reference repository의 --boxes JSON은 0부터 1까지의 실수 좌표를 쓴다.[1][3] 순서는 같아도 같은 JSON을 그대로 재사용하면 안 된다.

편집에서 대상을 옮길 때는 src_bbox와 tgt_bbox를 함께 쓴다. from은 어느 참조 이미지에서 내용을 가져오는지 지정한다. 같은 위치를 보존하려는 영역은 source와 target box를 같게 둔다. 그러나 이 표기는 모델에 주는 조건이지 pixel copy 명령은 아니다.

공식 문서는 box가 배치와 크기를 안내하지만 hard mask처럼 픽셀을 제한하지 않는다고 분명히 밝힌다.[2] 따라서 box 밖의 배경이 바뀔 수 있다. 대상의 그림자나 머리카락이 box를 넘어갈 수도 있다. 서로 겹치는 box는 모델이 의미적으로 재조정할 수 있다. 규정 준수나 정확한 제품 합성이 필요한 작업이라면 후처리 mask와 검수 단계를 별도로 둬야 한다.

이 차이는 제품 설계에 직접 영향을 준다. 광고 시안의 대략적인 구도에는 soft layout control이 유용하다. 전자상거래 상품의 실제 치수와 색상을 증명하는 용도로는 부족하다. 의료 영상이나 법적 증거에서 원본 영역 보존을 요구하는 편집에도 맞지 않는다. 생성 모델의 “그럴듯함”은 원본 보존의 증거가 아니다.

먼저 좌표 계약을 검증한다

GPU를 쓰기 전에 prompt와 box를 정적으로 검사할 수 있다. 다음 Python은 Diffusers inline 형식 전용으로 y-first 순서, 0~1000 정수 범위, 양의 면적, 중복 ID를 검사한다. Reference CLI에는 0~1 실수 schema 또는 명시적 변환 단계를 별도로 둬야 한다. 파일을 쓰거나 모델을 호출하지 않으므로 CI의 dry-run gate로 사용할 수 있다.

import json

layout = [
    {
        "id": "product_1",
        "bbox": [180, 90, 880, 610],
        "desc": "A matte black travel backpack viewed from the front"
    },
    {
        "id": "badge_1",
        "bbox": [80, 720, 260, 950],
        "desc": "A small cream promotional badge with bold black text"
    }
]

def validate_layout(regions):
    ids = set()
    for region in regions:
        required = {"id", "bbox", "desc"}
        missing = required - region.keys()
        assert not missing, (region.get("id"), sorted(missing))
        assert region["id"] not in ids, f"duplicate id: {region['id']}"
        ids.add(region["id"])
        y0, x0, y1, x1 = region["bbox"]
        assert all(isinstance(v, int) for v in (y0, x0, y1, x1))
        assert 0 <= y0 < y1 <= 1000, region["bbox"]
        assert 0 <= x0 < x1 <= 1000, region["bbox"]
    return json.dumps(regions, ensure_ascii=False, separators=(",", ":"))

print(validate_layout(layout))

정적 검사는 좌표 오타를 잡지만 이미지 품질을 보장하지 않는다. Region 설명이 caption과 충돌하는지도 별도 검사해야 한다. Caption은 “왼쪽”이라고 쓰고 box는 오른쪽에 두면 모델이 어느 조건을 우선할지 예측하기 어렵다. ID가 caption에 실제로 등장하는지도 확인해야 한다.

실무에서는 JSON schema를 repository에 고정하는 편이 좋다. 요청마다 canonical JSON을 만들고 hash를 기록하면 재현성도 높아진다. 원본 prompt, upsampled prompt, reference image digest, model revision, seed를 한 manifest에 묶는다. 결과 이미지만 보관하면 나중에 무엇이 달라졌는지 알 수 없다.

다음은 caption과 Diffusers inline layout을 결합하는 최소 예시다. Box가 절대 픽셀 좌표가 아니라 0~1000 grid라는 점을 코드에 드러냈다. 이 결과를 reference CLI의 --boxes에 전달하려면 각 값을 1000으로 나누어야 한다.

import json

caption = (
    "A clean studio product photograph of a matte black backpack <product_1> "
    "on a warm gray background, with a cream sale badge <badge_1>."
)
layout_json = json.dumps(layout, ensure_ascii=False)
prompt = f"{caption} {layout_json}"
print(prompt)

Distilled 모델을 실행하는 최소 경로

Diffusers 발표 문서는 최신 diffusers와 transformers 설치를 안내한다.[1] 재현 가능한 환경에서는 날짜에 따라 움직이는 최신 버전 대신 검증한 lockfile을 남겨야 한다. 아래 명령은 격리 환경을 만들고 package를 설치하는 시작점이다. Production image에서는 wheel hash와 CUDA 조합도 고정해야 한다.

python3 -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -U diffusers transformers accelerate safetensors torch pillow

Distilled checkpoint의 기본 생성 경로는 다음처럼 구성할 수 있다. 같은 seed를 사용해야 prompt만 바꾼 비교가 가능하다. output="images" 계약은 Modular Diffusers 예제를 따른다.[1]

import torch
from diffusers import ModularPipeline

MODEL_ID = "black-forest-labs/flux-3-image-klein"
SEED = 20261017

pipe = ModularPipeline.from_pretrained(MODEL_ID)
pipe.load_components(dtype=torch.bfloat16)
pipe.to("cuda")

image = pipe(
    prompt=prompt,
    generator=torch.Generator(device="cuda").manual_seed(SEED),
    height=1024,
    width=1024,
    num_inference_steps=16,
    output="images",
)[0]
image.save("layout-seed-20261017.png")

이 예제는 “실행 가능”하지만 모든 GPU에서 “실행 가능”하다는 뜻은 아니다. Weight download 권한과 저장 공간이 필요하다. BF16을 지원하는 CUDA GPU도 필요하다. Package 최신 조합이 모델 공개 시점과 달라지면 API가 바뀔 수 있다. Production에서는 reference repository의 검증된 dependency와 Diffusers 경로를 각각 별도 lane으로 시험한다.

다중 참조 편집에서는 입력 순서를 manifest에 명시한다. 파일명만 믿지 말고 SHA-256과 index를 함께 기록한다. Prompt의 <ref_image_0>이 실제 첫 번째 배열 원소와 맞는지 unit test한다. UI에서 drag-and-drop 순서가 바뀌는 문제도 흔한 실패 원인이다.

from PIL import Image

references = [
    Image.open("person.png").convert("RGB"),
    Image.open("backpack.png").convert("RGB"),
]
edit_prompt = (
    "A studio photograph of the person from <ref_image_0> wearing the matte black "
    "backpack from <ref_image_1>, preserving the person's face and the backpack logo."
)

result = pipe(
    prompt=edit_prompt,
    image=references,
    generator=torch.Generator(device="cuda").manual_seed(SEED),
    output="images",
)[0]
result.save("multi-reference-seed-20261017.png")

이 코드는 identity preservation을 검증하지 않는다. 결과를 저장했을 뿐이다. 얼굴, 로고, 색상, 손가락 수, 배경 보존은 자동 평가나 사람 검수로 확인해야 한다. 참조 이미지에 대한 권리와 개인정보 처리 근거도 모델 실행 성공과 별개의 문제다.

Prompt upsampler를 공짜 전처리로 보면 안 된다

Klein은 짧은 요청보다 충분한 장면 설명에서 더 잘 작동하도록 설계됐다.[2] 공식 CLI와 Python API는 prompt upsampler 사용을 강하게 권장한다. Upsampler는 편의 기능이지만 결과에 영향을 주는 또 하나의 모델이다. 같은 사용자 prompt라도 upsampler version이나 system prompt가 바뀌면 최종 caption이 달라질 수 있다.

따라서 원문 prompt와 확장 prompt를 모두 보관해야 한다. 확장기가 부정 표현을 약화하거나 브랜드명을 일반화할 수 있다. 사용자가 지시하지 않은 인구학적 특성이나 배경 요소를 추가할 수도 있다. 보안 필터를 원문에만 적용하면 확장 후 금지 조건이 새로 생길 수 있다.

Upsampler를 끈 실험도 baseline으로 남긴다. 품질이 낮아져도 그 차이가 transformer 때문인지 prompt expansion 때문인지 분리할 수 있다. Latency 측정에서는 expansion 시간을 별도 구간으로 기록한다. GPU memory 측정에서도 upsampler load와 image transformer load를 나눠야 한다.

공식 reference 자료는 80GB GPU에서 upsampler 기본 예약 비율을 0.35로 두며 약 28GB를 더 사용할 수 있다고 설명한다.[3] 이 값은 model card의 image transformer peak와 같은 의미가 아니다. 실제 peak는 allocator, 동시성, offload, reference 수에 따라 달라진다. “5.6B니까 16GB GPU면 충분하다” 같은 단순 계산이 위험한 이유다.

BF16·FP8·NVFP4를 같은 조건에서 비교한다

공식 reference code가 B200, 1,024×1,024, prompt upsampler off 조건에서 보고한 distilled peak GPU memory는 BF16 31GB, FP8 26GB, NVFP4 25GB다.[3] 이 수치는 nvidia-smi 기반 공급자 측정이다. Base checkpoint에서는 같은 표가 BF16 31GB, FP8 29GB, NVFP4 26GB로 제시된다. 이 결과를 다른 GPU나 Diffusers implementation의 보장값으로 옮기면 안 된다.

FP8 경로는 Ada, Hopper, Blackwell 계열을 요구한다. NVFP4는 Blackwell과 추가 dependency를 요구한다. Reference code에서 NVFP4와 offload는 함께 쓰지 못한다.[3] 오래된 GPU에서 file이 로드된다는 사실과 해당 precision의 native acceleration을 얻는다는 사실은 다르다.

양자화 비교는 메모리 하나로 끝내면 안 된다. 같은 seed와 prompt에서 출력 품질이 얼마나 달라지는지 봐야 한다. Layout box에 들어온 대상 비율도 측정해야 한다. Reference identity similarity와 텍스트 정확도도 확인해야 한다. 낮은 정밀도에서 특정 색조나 작은 typography가 더 자주 깨지는지도 샘플별로 기록한다.

다음 조건을 고정하면 비교 결과를 해석하기 쉬워진다.

축 고정하거나 기록할 값
모델 distilled/base, exact revision, transformer variant
입력 원문·확장 prompt, reference digest·순서, layout JSON
생성 seed, step, guidance, width·height, batch size
시스템 GPU model, driver, CUDA, PyTorch, attention backend
부하 warm-up 수, 동시 요청 수, 측정 반복 수
결과 p50·p95 latency, peak VRAM, energy, 실패·OOM 수
품질 box IoU proxy, 비편집 영역 차이, identity·text 평가

공식 발표는 distilled checkpoint가 H100에서 1,024×1,024 이미지를 약 2초에 만든다고 적는다.[1] Reference repository의 별도 비교는 한 H200, 1MP에서 distilled 약 3초, Base 약 12초라고 보고한다.[3] Hardware와 실행 stack이 다르므로 두 숫자를 직접 나눠 속도 향상률을 만들면 안 된다. 둘 다 공급자 보고 수치이며 독립 benchmark가 아니다.

Reference repository는 distilled가 Base보다 약 6배 빠르다고 설명하지만 함께 제시된 H200 단일 예시는 약 3초 대 12초다.[3] Step 수만 보면 16 대 50이지만 실제 latency는 CFG, kernel, text encoding, upsampler, I/O의 영향을 받는다. “16 step이니 항상 50 step의 32% 시간”이라고 예측할 수 없다. 자체 측정에서는 전체 요청과 denoising 구간을 둘 다 기록한다.

비용은 이미지 한 장의 GPU 초보다 넓다

Self-hosting 비용은 GPU 대여료를 생성 수로 나누는 계산부터 시작한다. 그러나 idle 시간, 실패 재시도, model load, cache, object storage, moderation, 검수 인력을 빼면 결과가 지나치게 낙관적이다. 다음 식은 회계 기준이 아니라 누락 방지용 운영 모델이다.

cost_per_accepted_image =
    (gpu_runtime
   + idle_capacity
   + prompt_upsampler_runtime
   + storage_and_egress
   + moderation_and_review
   + failed_and_retried_generations
   + engineering_and_oncall)
  / accepted_images

분모는 generated image가 아니라 accepted image로 두는 편이 정확하다. Box를 벗어나 폐기한 이미지도 GPU 비용을 썼다. 참조 identity가 섞여 재생성한 이미지도 비용에 포함된다. 사람 검수에서 탈락한 결과를 제외하지 말고 실패 비용으로 분자에 남긴다.

양자화가 메모리를 줄여도 자동으로 비용이 줄지는 않는다. FP8이나 NVFP4 kernel이 대상 GPU에서 충분히 빠르지 않으면 latency가 늘 수 있다. 메모리 절감으로 동시성을 높였을 때 queue tail이나 품질 재시도가 증가할 수도 있다. 한 GPU에 더 많은 worker를 넣으면 upsampler와 decoder의 memory peak가 겹칠 수 있다.

API와 self-hosting도 같은 단위로 비교해야 한다. API 가격에는 provider의 idle capacity와 운영비가 포함된다. Self-hosting 계산에는 예약 GPU의 비사용 시간까지 넣는다. 보안 검토와 license eligibility를 위한 내부 비용도 무시할 수 없다. 트래픽이 작고 불규칙하면 높은 GPU utilization을 전제로 한 단가가 성립하지 않는다.

보안과 데이터 경계

참조 이미지는 단순 prompt보다 민감할 수 있다. 얼굴, 사내 디자인, 출시 전 상품, 위치 metadata가 포함될 수 있다. Upload 전에 EXIF를 제거하고 허용된 MIME과 실제 decode 결과를 검사한다. 원본과 생성물의 저장 기간도 분리한다.

Image decoder는 공격 표면이다. 확장자와 content type만 믿지 않는다. Decode를 낮은 권한의 격리 process에서 수행한다. 해상도와 pixel 수 상한을 두고 decompression bomb를 거부한다. 처리 실패 파일을 운영자가 로컬 viewer로 직접 열지 않도록 한다.

Model artifact도 supply-chain 입력이다. Mutable branch 대신 검토한 revision을 고정한다. Safetensors와 manifest digest를 확인한다. trust_remote_code가 필요한 경로는 실행 코드를 별도 review한다. Container에는 장기 cloud credential을 넣지 않는다.

Prompt와 reference를 observability에 그대로 남기는 것도 위험하다. 운영 log에는 request ID, hash, policy decision, timing만 남기고 원문 보존은 별도 권한과 retention을 적용한다. Debug sample은 사용자 동의와 접근 감사를 요구할 수 있다. Metrics label에 prompt나 사용자 ID를 넣으면 정보 유출과 cardinality 폭증이 함께 생긴다.

생성물 안전 필터도 모델 라이선스와 제품 정책을 모두 봐야 한다. 입력 필터만으로 충분하지 않다. Upsampler가 바꾼 prompt와 최종 이미지에도 정책을 적용한다. False positive와 false negative를 측정하고 appeal 경로를 둔다. 필터 장애 시 fail-open인지 fail-closed인지 제품 위험에 맞게 결정한다.

자주 발생하는 실패 모드

Box 순서가 뒤집힌다

팀원이 [x_min, y_min, x_max, y_max]로 가정하면 대상이 전혀 다른 위치에 생긴다. Schema와 변수명을 y0, x0, y1, x1로 강제한다. 시각화 overlay를 generation 전에 만든다. 좌표 계약은 문서보다 테스트로 고정하는 편이 낫다.

Box 안에 있지만 구도가 틀린다

대상의 일부만 box 안에 들어오거나 시선 방향이 바뀔 수 있다. 중심점 오차와 면적 비율을 함께 측정한다. 단일 IoU threshold만으로 사람의 구도 판단을 대체하지 않는다. Box는 soft condition이라는 경계를 사용자에게도 보여준다.

참조 속성이 서로 섞인다

첫 이미지의 얼굴과 두 번째 이미지의 머리색이 섞일 수 있다. Reference별 보존할 속성과 바꿀 속성을 prompt에 명시한다. 한 번에 10장을 넣을 수 있다는 최대치가 10장 모두를 안정적으로 구분한다는 보장은 아니다. 참조 수를 늘리며 품질이 꺾이는 지점을 측정한다.

비편집 영역이 바뀐다

“나머지는 그대로”라는 문장만으로 pixel preservation을 기대하면 안 된다. 원본과 결과의 비편집 mask에서 LPIPS나 구조 차이를 측정할 수 있다. 정확한 보존이 필요하면 생성 결과를 원본에 합성하는 deterministic post-process를 검토한다. 그래도 경계 halo와 조명 불일치는 사람 검수가 필요하다.

Seed가 같아도 결과가 달라진다

Model revision, CUDA kernel, attention backend, package version이 바뀌면 seed만 같아도 bit-identical하지 않을 수 있다. 재현 manifest에 software와 hardware를 포함한다. Acceptance는 pixel equality보다 허용 가능한 품질 범위를 기준으로 둔다. 규제 증거가 필요하면 원본 artifact와 실행 환경을 함께 보존한다.

Quantized variant가 로드되지만 느리다

지원되지 않는 hardware에서 dequantization overhead가 이득을 상쇄할 수 있다. Warm-up 후 p50만 보지 말고 cold start와 p95도 기록한다. Batch와 concurrency를 바꿔 kernel utilization을 확인한다. Memory 절감과 throughput 향상을 같은 주장으로 묶지 않는다.

Prompt upsampler가 지시를 바꾼다

확장 prompt diff를 저장하고 금지어·부정문·고유명사 보존을 검사한다. 중요한 위치와 identity constraint는 확장 후에도 존재해야 한다. Upsampler update는 모델 update와 같은 rollout gate를 거친다. 사용자 원문을 보여주면서 확장 결과도 감사할 수 있게 한다.

OOM이 간헐적으로 발생한다

Reference 수, 입력 해상도, 동시성, upsampler 상주 여부가 peak를 바꾼다. 단일 happy-path memory 표로 capacity를 잡지 않는다. 가장 큰 허용 입력과 concurrent request를 조합한 stress test가 필요하다. OOM 뒤 worker가 정상 request를 처리하는지도 확인한다.

도입과 업그레이드 gate

첫 단계는 weight를 받기 전에 license와 데이터 경계를 승인하는 것이다. 두 번째 단계는 synthetic reference만으로 prompt·layout parser를 검증하는 것이다. 세 번째 단계는 BF16 단일 worker에서 golden fixture를 만든다. 네 번째 단계에서 FP8과 NVFP4를 같은 fixture로 비교한다.

다섯 번째 단계는 실제 트래픽 분포를 닮은 reference 수와 해상도로 부하를 건다. 여섯 번째 단계는 policy filter, storage, deletion, audit log를 포함한 end-to-end 경로를 시험한다. 일곱 번째 단계는 제한된 사용자에게 canary를 열고 accepted-image cost를 측정한다. 어느 단계든 품질 재시도율과 p95 latency가 기준을 넘으면 확대를 중단한다.

Upgrade 때는 model revision만 바꾸지 않는다. Prompt upsampler와 system prompt revision을 함께 기록한다. Diffusers와 reference implementation 결과가 허용 범위 안에 있는지 비교한다. Quantization artifact가 바뀌면 각 precision의 golden set을 다시 실행한다.

Rollback도 실제로 시험해야 한다. 새 worker가 만든 manifest를 이전 version이 읽을 수 있는지 확인한다. Cache key에 model과 upsampler revision이 포함되는지 확인한다. 새 결과와 이전 결과가 같은 object key를 덮어쓰지 않게 한다. Content policy 변경은 model rollback과 독립적으로 되돌릴 수 있어야 한다.

이미지 생성·편집에 적합한 팀과 도입이 어려운 조건

적합한 경우

  • 여러 참조를 조합한 시안과 반복 편집이 핵심인 creative tool을 만든다.
  • 대략적인 공간 제어를 자연어와 box로 함께 제공하고 싶다.
  • Self-hosting이 필요하고 weight·prompt·reference를 자체 환경에서 관리할 수 있다.
  • BF16·FP8·NVFP4의 품질과 비용을 자기 GPU에서 비교할 인력이 있다.
  • 커스텀 라이선스와 content filtering 의무를 지속적으로 검토할 수 있다.

부적합한 경우

  • Box 밖 pixel이 절대로 바뀌면 안 되는 deterministic 편집이 필요하다.
  • 제품 이미지의 치수·색상·로고가 사실임을 생성 결과로 증명해야 한다.
  • 5.6B라는 숫자만 보고 text encoder와 upsampler 자원을 예산에서 제외한다.
  • “공개 가중치”를 Apache-2.0 오픈소스와 같은 뜻으로 사용하려 한다.
  • GPU 운영, moderation, reference image 개인정보 보호를 맡을 팀이 없다.

정확한 mask 편집이 목적이면 segmentation과 compositing pipeline이 더 예측 가능할 수 있다. 단순한 template 광고라면 HTML·SVG renderer가 더 싸고 감사하기 쉽다. 한 장의 text-to-image만 필요하면 더 작은 모델이나 managed API가 운영 부담을 줄일 수 있다. FLUX.3 Image Klein의 강점은 모든 이미지 작업을 대체하는 데 있지 않고, 여러 조건을 하나의 generative workflow에서 빠르게 탐색하는 데 있다.

결론: 좌표를 입력으로 받는 것과 좌표를 지키는 것은 다르다

FLUX.3 Image Klein은 text-to-image, 최대 10장 참조 편집, 정규화 bounding-box layout을 하나의 공개 가중치 모델 계열로 묶었다. Distilled와 Base, BF16·FP8·NVFP4, prompt upsampler와 Modular Diffusers라는 선택지도 제공한다. 이 조합은 prototype의 표현력을 크게 높인다. 동시에 무엇을 측정해야 하는지도 늘린다.

Box는 hard mask가 아니다. 5.6B는 전체 pipeline 크기가 아니다. FP8과 NVFP4의 작은 memory 표는 모든 GPU의 비용표가 아니다. 공급자가 보고한 H100·H200 latency도 자기 서비스의 accepted-image latency가 아니다.

따라서 production 판단은 같은 seed의 예쁜 두 장보다 긴 evidence bundle을 요구한다. 원문과 확장 prompt, 참조 digest와 순서, layout JSON, model·variant revision, hardware·software 조건, latency·VRAM, box 준수, 비편집 영역 차이, 탈락 사유를 함께 남겨야 한다. 그 기록이 있어야 BF16에서 FP8로 바꾼 뒤 비용이 정말 내려갔는지 설명할 수 있다. 그 기록이 있어야 “레이아웃 제어”가 제품이 요구한 제어 수준에 도달했는지도 답할 수 있다.

Sources

[1] https://huggingface.co/blog/flux-3 — Welcome FLUX.3 Image Klein in Diffusers [2] https://huggingface.co/black-forest-labs/flux-3-image-klein — FLUX.3 Image Klein model card and license boundary [3] https://github.com/black-forest-labs/flux-3-image-klein — Reference inference code, installation, memory and latency notes