कोर्स
FLUX.2 Klein को तेज, इंटरैक्टिव इमेज वर्कफ़्लो के लिए डिज़ाइन किया गया है जहाँ आप न्यूनतम विलंबता के साथ जनरेट, रिफाइन और इटरेट कर सकते हैं। इस ट्यूटोरियल में, मैं Google Colab में Gradio के साथ एक हल्का-फुल्का “Generate and Edit एप्लिकेशन” बनाने के लिए FLUX.2 Klein 4B का उपयोग करूँगा।
ऐप में, उपयोगकर्ता पहले एक जेनरेशन प्रॉम्प्ट दर्ज करके बेस इमेज बनाता है, फिर वैकल्पिक रेफरेंस इमेज के साथ एक एडिट निर्देश देता है ताकि संशोधन को निर्देशित किया जा सके। हर संस्करण सेशन हिस्ट्री में सहेजा जाता है, ताकि उपयोगकर्ता किसी भी पिछले आउटपुट को फिर से लोड कर सके और वहीं से प्रयोग जारी रख सके।
परिणाम एक इंटरैक्टिव एडिटर है जो तेज इटरेशन, भरोसेमंद इमेज एडिटिंग, और हिस्ट्री-चालित वर्कफ़्लो को उजागर करता है—जो केवल एक मॉडल कॉल की तुलना में वास्तविक प्रोडक्ट अनुभव के अधिक करीब है।
मैं आपको हमारा FLUX.2 बेस ट्यूटोरियल और FLUX.2 को लोकली चलाने की गाइड भी देखने की सलाह देता हूँ। यदि आप अन्य इमेज जेनरेशन मॉडलों में भी रुचि रखते हैं, तो Google के Nano Banana 2 पर हमारी गाइड ज़रूर पढ़ें।
FLUX.2 [klein] 4B क्या है?
FLUX.2 इमेज मॉडलों का एक परिवार है जिसे अलग-अलग संतुलनों के लिए ट्यून किया गया है। इसमें कई वेरिएंट शामिल हैं जो गुणवत्ता, गति और लचीलेपन के विभिन्न स्तरों के लिए अनुकूलित हैं। FLUX.2 Klein लाइन इंटरैक्टिव विज़ुअल इंटेलिजेंस पर केंद्रित है, यानी मॉडल को तेज़ी से प्रतिक्रिया देने, शीघ्रता से इटरेट करने और सुलभ हार्डवेयर पर कुशलतापूर्वक चलने के लिए बनाया गया है।
FLUX.2 Klein परिवार टेक्स्ट-टू-इमेज जनरेशन, इमेज एडिटिंग और मल्टी-रेफरेंस कंडीशनिंग को सपोर्ट करता है।
![FLUX.2 [klein] Elo vs Latency (top) and VRAM (bottom) across Text-to-Image, Image-to-Image Single Reference, and Multi-Reference tasks](https://media.datacamp.com/cms/ed3132d0735b33e6296bb485e0638899.png)
चित्र: टेक्स्ट-टू-इमेज, इमेज-टू-इमेज सिंगल रेफरेंस, और मल्टी-रेफरेंस कार्यों में FLUX.2 [klein] Elo बनाम लेटेंसी (ऊपर) और VRAM (नीचे) (Flux 2 ब्लॉग)
Klein 4B वेरिएंट Klein परिवार में सबसे डेवलपर-फ्रेंडली विकल्प है क्योंकि यह Apache 2.0 लाइसेंस के तहत पूरी तरह ओपन है और लगभग 13GB VRAM वाले कंज्यूमर GPUs पर चलाने के लिए डिज़ाइन किया गया है।
FLUX.2 Klein की प्रमुख क्षमताएँ
- रीयल-टाइम इटरेशन: Klein उन वर्कफ़्लो के लिए डिज़ाइन किया गया है जहाँ आप जनरेट करते हैं और फिर तेजी से रिफाइन करते हैं। यह इंटरैक्टिव प्रीव्यू लूप्स और UI-चालित एडिटिंग अनुभवों के लिए उपयुक्त है।
- एकीकृत जनरेशन और एडिटिंग: जनरेशन और एडिटिंग को अलग-अलग प्रोडक्ट फीचर मानने के बजाय, Klein मॉडल परिवार दोनों का समर्थन करने के लिए बनाया गया है।
- मल्टी-रेफरेंस सपोर्ट: Klein मल्टी-रेफरेंस जनरेशन और एडिटिंग को सपोर्ट करता है, जो पैलेट इमेज, स्टाइल रेफरेंस या ऑब्जेक्ट रेफरेंस का उपयोग करके एडिट्स को ग्राउंड करने में सहायक है। आधिकारिक API में, Klein एंडपॉइंट एडिटिंग के लिए कुल चार इमेज तक सपोर्ट करता है, जो एक बेस इमेज और अधिकतम तीन रेफरेंस के अनुरूप बैठता है।
Klein आमतौर पर दो व्यापक प्रकारों में आता है: स्पीड के लिए अनुकूलित डिस्टिल्ड मॉडल और लचीलेपन के लिए अनुकूलित बेस फाउंडेशन मॉडल। Klein 4B डिस्टिल्ड मॉडल इंटरैक्टिव ऐप्स बनाने के लिए व्यावहारिक विकल्प है, जबकि बेस वेरिएंट तब अधिक उपयुक्त हैं जब आप अधिक लेटेंसी के बावजूद अधिकतम फाइन-ट्यूनिंग लचीलापन और नियंत्रण चाहते हैं।
FLUX.2 Klein ट्यूटोरियल: इमेज जनरेशन और एडिटिंग ऐप
इस अनुभाग में, हम FLUX.2 Klein का उपयोग करते हुए दो-चरणीय इमेज वर्कफ़्लो लागू करेंगे, जिसे एक Gradio एप्लिकेशन में लपेटा गया है। उच्च स्तर पर, ऐप तीन मुख्य कार्य करता है:
- टेक्स्ट प्रॉम्प्ट से एक बेस इमेज जनरेट करें
- वैकल्पिक रेफरेंस द्वारा ग्राउंड किए गए दूसरे निर्देश प्रॉम्प्ट का उपयोग करके जनरेट की गई इमेज को एडिट करें।
- अंत में, आसान अन्वेषण के लिए सेशन हिस्ट्री बनाए रखें। उपयोगकर्ता हिस्ट्री ड्रॉपडाउन से किसी भी पिछली इमेज को लोड कर सकता है और एडिट लागू कर सकता है।
पर्दे के पीछे, यह वर्कफ़्लो दो पूरक फ़ंक्शनों द्वारा संचालित होता है:
local_generate()फ़ंक्शन Diffusers लाइब्रेरी का उपयोग करके FLUX.2 Klein 4B को लोकली तेजtext-to-imageजनरेशन के लिए चलाता है।bfl_edit(edit_prompt, base_img, ref_imgs)फ़ंक्शन Black Forest Labs के होस्ट किए गए FLUX.2 Klein एडिटिंग API को इमेज एडिटिंग अनुरोध भेजता है, फिर एडिट की गई इमेज तैयार होने तक लौटाए गएpolling_urlको बार-बार पोल करता है।
हिस्ट्री मैकेनिज़्म जनरेट की गई इमेज को एक डिक्शनरी के रूप में संग्रहीत करता है जिसमें इमेज और एक छोटा लेबल होता है: {"img": PIL.Image, "label": str}।
नीचे दिए गए वीडियो में, आप वर्कफ़्लो का एक संक्षिप्त संस्करण देख सकते हैं। प्रदर्शन उद्देश्यों के लिए वीडियो को तेज़ किया गया है:
चरण 1: परिवेश सेटअप
इमेज जनरेशन और एडिटिंग ऐप बनाने से पहले, हमें नवीनतम Diffusers लाइब्रेरी के साथ एक स्वच्छ परिवेश स्थापित करना होगा। इस ट्यूटोरियल के लिए, हम Google Colab इंस्टेंस पर A100 GPU के साथ सब कुछ चलाएँगे ताकि इमेज जनरेशन तेज़ हो। फिर भी, वही सेटअप थोड़े कम प्रदर्शन के साथ T4 जैसे अधिक मामूली GPUs पर भी काम करता है।
हम वर्ज़न कॉन्फ्लिक्ट से बचने के लिए किसी भी मौजूदा Diffusers वर्ज़न को अनइंस्टॉल करके शुरू करते हैं, फिर GitHub से सीधे नवीनतम डेवलपमेंट वर्ज़न इंस्टॉल करते हैं। हम मॉडल लोडिंग, चेकपॉइंट हैंडलिंग और एक्सीलरेशन के लिए आवश्यक सहायक लाइब्रेरी भी इंस्टॉल करते हैं।
!pip -q uninstall -y diffusers
!pip -q install -U git+https://github.com/huggingface/diffusers.git
!pip -q install -U accelerate safetensors transformers huggingface_hub
इंस्टॉलेशन पूरा होने के बाद, हम इंस्टॉल की गई Diffusers वर्ज़न की जाँच करते हैं, फिर यह पुष्टि करते हैं कि Flux2KleinPipeline क्लास सफलतापूर्वक इम्पोर्ट हो सकती है।
import diffusers
print("diffusers:", diffusers.__version__)
from diffusers import Flux2KleinPipeline
print("Flux2KleinPipeline import OK")
यह पुष्टि करता है कि हमारा परिवेश सही तरीके से कॉन्फ़िगर किया गया है। अगले चरण में, हम FLUX.2 Klein मॉडल को GPU पर लोड करेंगे और इसे स्थानीय इमेज जनरेशन और API-आधारित एडिटिंग वर्कफ़्लो दोनों के लिए तैयार करेंगे।
चरण 2: FLUX.2 Klein 4B लोड करें
मॉडल लोड करने से पहले, आपको Black Forest Labs से एक API कुंजी की आवश्यकता है। आरंभ करने के लिए, अपने Black Forest Labs खाते में लॉग इन करें और Credits टैब के अंतर्गत क्रेडिट जोड़ें। न्यूनतम टॉप-अप लगभग दस डॉलर है, जो लगभग एक हज़ार क्रेडिट प्रदान करता है। क्रेडिट जोड़ने के बाद, Create Key पर क्लिक करें, इसका वर्णनात्मक नाम दें और इसे सुरक्षित रूप से संग्रहीत करें।

API कुंजी तैयार होने के साथ, अगला चरण FLUX.2 Klein 4B मॉडल लोड करना है और इसे दो अलग-अलग उपयोग मोड के लिए तैयार करना है: स्थानीय इमेज जनरेशन और API-आधारित इमेज एडिटिंग।
import os, time, base64, io, requests
import gradio as gr
import torch
import nest_asyncio
from PIL import Image
from diffusers import Flux2KleinPipeline
from google.colab import userdata
nest_asyncio.apply()
# =============================
# LOAD via API
# =============================
MODEL_ID = "black-forest-labs/FLUX.2-klein-4B"
BFL_API_KEY = userdata.get("BFL_API_KEY")
BFL_CREATE_URL = "https://api.bfl.ai/v1/flux-2-klein-4b"
print(f"Loading model to GPU: {torch.cuda.get_device_name(0)}")
# =============================
# LOAD via LOCAL HF PIPELINE
# =============================
dtype = torch.float16
pipe = Flux2KleinPipeline.from_pretrained(MODEL_ID, torch_dtype=dtype).to("cuda")
हम API कुंजी को Colab सीक्रेट के रूप में सेटअप करके शुरू करते हैं, ताकि यह नोटबुक कोड में कभी दिखाई न दे। हम मॉडल ID और Klein एडिटिंग एंडपॉइंट भी परिभाषित करते हैं जिसे हम बाद में कॉल करेंगे।
अगला, हम Gradio UI लॉन्च करने से पहले इवेंट लूप कॉन्फ्लिक्ट से बचने के लिए nest_asyncio लागू करते हैं।
अंत में, बेस इमेज जनरेशन के लिए स्थानीय FLUX.2 Klein पाइपलाइन लोड करें। हम Flux2KleinPipeline को float16 के साथ व्यापक GPU संगतता (A100 और T4 दोनों अच्छी तरह काम करते हैं) के लिए उपयोग करते हैं, फिर तेज इन्फरेंस के लिए पाइपलाइन को CUDA पर ले जाते हैं। यह स्थानीय पाइपलाइन केवल प्रारंभिक इमेज जनरेट करने के लिए उपयोग की जाती है, जबकि एडिट्स API के माध्यम से हैंडल होते हैं।
नोट: इस बिंदु पर, आप सोच सकते हैं कि हम मॉडल को लोकली भी लोड क्यों करते हैं और API एक्सेस भी कॉन्फ़िगर क्यों करते हैं। कारण है क्षमताओं का विभाजन:
- स्थानीय Hugging Face पाइपलाइन, इटरेटिव टेक्स्ट-टू-इमेज जनरेशन और इन्फरेंस सेटिंग्स पर पूर्ण नियंत्रण के लिए आदर्श है।
- Black Forest Labs API, FLUX.2 Klein के उन्नत इमेज एडिटिंग फीचर्स को एक्सपोज़ करता है जो अभी ओपन-वेट इम्प्लीमेंटेशन में उपलब्ध नहीं हैं, जैसे मल्टीपल रेफरेंस इमेज के साथ प्रॉम्प्ट-आधारित इमेज एडिट्स।
दोनों तरीकों को मिलाकर, हमें दोनों दुनियाओं का सर्वश्रेष्ठ मिलता है: स्थानीय जनरेशन स्पीड और एडिटिंग सपोर्ट।
चरण 3: हेल्पर फ़ंक्शंस
Gradio इंटरफ़ेस में सब कुछ वायर करने से पहले, हमें कुछ छोटे हेल्पर फ़ंक्शंस की आवश्यकता है। चूँकि हमारा ऐप इमेजेस लोकली जनरेट करता है लेकिन उन्हें API के माध्यम से एडिट करता है, हमें API अनुरोधों के लिए इमेजेस को base64 में एन्कोड करने का तरीका, URLs के रूप में लौटाई गई एडिट की गई इमेजेस को डाउनलोड करने का तरीका, और प्रारंभिक बेस इमेज बनाने वाला स्थानीय जनरेशन फ़ंक्शन चाहिए।
def pil_to_b64_png(img: Image.Image) -> str:
buf = io.BytesIO()
img.convert("RGB").save(buf, format="PNG")
return base64.b64encode(buf.getvalue()).decode()
def url_to_pil(url: str) -> Image.Image:
r = requests.get(url, timeout=60)
r.raise_for_status()
return Image.open(io.BytesIO(r.content)).convert("RGB")
def local_generate(prompt: str):
if not prompt.strip():
raise gr.Error("Prompt is empty.")
out = pipe(
prompt=prompt.strip(),
width=1024,
height=1024,
num_inference_steps=4,
guidance_scale=1.0,
output_type="pil",
)
return out.images[0].convert("RGB")
उपरोक्त कोड तीन प्रमुख हेल्पर फ़ंक्शंस परिभाषित करता है:
pil_to_b64_png()फ़ंक्शन एक PIL इमेज को base64-एन्कोडेड PNG स्ट्रिंग में बदलता है। यह आवश्यक है क्योंकि FLUX.2 एडिटिंग API बेस इमेज और रेफरेंस इमेज को URLs या base64 स्ट्रिंग्स के रूप में स्वीकार करता है।url_to_pil()फ़ंक्शन विपरीत दिशा को संभालता है। एडिटिंग API जेनरेटेड आउटपुट के लिए एक साइन किया हुआ URL लौटाता है, इसलिए हमrequestsके साथ वह URL फ़ेच करते हैं, प्रतिक्रिया को मान्य करते हैं, और डाउनलोड किए गए बाइट्स को वापस PIL इमेज में बदलते हैं। इससे एडिट किया गया परिणाम सीधे हमारे Gradio इंटरफ़ेस में प्रदर्शित किया जा सकता है और हिस्ट्री में सहेजा जा सकता है।- अंततः,
local_generate()फ़ंक्शन हमारा स्थानीय टेक्स्ट-टू-इमेज एंट्री पॉइंट है। यह सत्यापित करता है कि प्रॉम्प्ट खाली नहीं है, फिरFlux2KleinPipelineको फिक्स्ड सेटिंग्स जैसे रिज़ॉल्यूशन, स्टेप काउंट और गाइडेंस स्केल के साथ कॉल करता है। आउटपुट एक साफ़ RGB PIL इमेज के रूप में लौटाया जाता है, जो आगे के एडिट्स के लिए बेस इमेज बनती है।
FLUX पाइपलाइन सेटिंग्स—जैसे इमेज रिज़ॉल्यूशन, डिफ्यूज़न स्टेप्स और गाइडेंस स्केल—से खेलने में संकोच न करें, ताकि अलग-अलग गुणवत्ता-गति संतुलन तलाश सकें और समझ सकें कि हर पैरामीटर अंतिम इमेज को कैसे प्रभावित करता है।
Flux 2 इमेज एडिटिंग की डॉक्यूमेंटेशन इन सेटिंग्स के बारे में और समझने के लिए अच्छा स्थान है।
अगले चरण में, हम इन यूटिलिटीज़ का उपयोग करके FLUX.2 Klein के साथ API-आधारित इमेज एडिटिंग लागू करेंगे।
चरण 4: BFL API के माध्यम से एडिटिंग
यह चरण केवल Hugging Face वर्कफ़्लो और इस ट्यूटोरियल में उपयोग किए गए हाइब्रिड दृष्टिकोण के बीच का मूल अंतर है। इमेज एडिटिंग को लोकली चलाने का प्रयास करने के बजाय, हम एडिट्स को API को सौंपते हैं, जो प्रॉम्प्ट-आधारित एडिट्स और वैकल्पिक मल्टी-रेफरेंस कंडीशनिंग को विश्वसनीय रूप से संभालता है।
उच्च स्तर पर, FLUX.2 Klein एडिटिंग API एक टेक्स्ट प्रॉम्प्ट की अपेक्षा करता है जो एडिट का वर्णन करता है, संशोधित करने के लिए एक बेस इमेज, और अतिरिक्त इनपुट्स के रूप में वैकल्पिक रेफरेंस इमेजेस। API असिंक्रोनस रूप से चलता है, यानी हम अनुरोध सबमिट करते हैं और फिर एडिट की गई इमेज तैयार होने तक लौटाए गए URL को पोल करते हैं।
POLL_INTERVAL_S = 1.0
POLL_TIMEOUT_S = 120
def bfl_edit(edit_prompt, base_img, ref_imgs=None):
if not BFL_API_KEY:
raise gr.Error("Missing BFL_API_KEY in Colab Secrets.")
payload = {
"prompt": edit_prompt.strip(),
"input_image": pil_to_b64_png(base_img),
"output_format": "png",
}
if ref_imgs:
for i, ref in enumerate(ref_imgs[:3], start=2):
payload[f"input_image_{i}"] = pil_to_b64_png(ref)
create = requests.post(
BFL_CREATE_URL,
headers={"x-key": BFL_API_KEY, "accept": "application/json"},
json=payload,
timeout=60,
)
create.raise_for_status()
job = create.json()
polling_url = job.get("polling_url")
if not polling_url:
raise gr.Error(f"API Error: {job}")
t0 = time.time()
while True:
if time.time() - t0 > POLL_TIMEOUT_S:
raise gr.Error("BFL API polling timed out.")
time.sleep(POLL_INTERVAL_S)
res = requests.get(polling_url, headers={"x-key": BFL_API_KEY})
res.raise_for_status()
j = res.json()
if j["status"] == "Ready":
return url_to_pil(j["result"]["sample"])
if j["status"] in ("Error", "Failed"):
raise gr.Error(f"Generation Failed: {j}")
bfl_edit() फ़ंक्शन तीन महत्वपूर्ण कार्य करता है:
- यह तीन इनपुट लेता है, जिनमें एडिट प्रॉम्प्ट, वह बेस इमेज जिसे हम मॉडिफ़ाई करना चाहते हैं, और वैकल्पिक रेफरेंस इमेज की सूची शामिल है।
- हम एडिट प्रॉम्प्ट और बेस इमेज को
base64PNG के रूप में एन्कोड करके एक JSON पेलोड बनाते हैं। यदि रेफरेंस इमेजेस दी गई हैं, तो हम उन्हें API के इंडेक्सड फ़ॉर्मेट का उपयोग करके संलग्न करते हैं। इससे हम बेस इमेज के साथ अधिकतम तीन रेफरेंस इमेज सप्लाई कर सकते हैं, जो कई व्यावहारिक वर्कफ़्लो—जैसे कलर पैलेट ट्रांसफ़र, स्टाइल एंकरिंग, या ऑब्जेक्ट ग्राउंडिंग—के लिए पर्याप्त है। - इसके बाद, हम अनुरोध को API एंडपॉइंट पर सबमिट करते हैं और प्रतिक्रिया को पार्स करते हैं। API एक
polling_urlलौटाता है जिसे हमें जॉब समाप्त होने तक बार-बार क्वेरी करना होता है। हम इसे एक साधारण पोलिंग लूप से लागू करते हैं जिसमें दो गार्डरेल हैं: अत्यधिक अनुरोधों से बचने के लिए एक पोलिंग इंटरवल और अनिश्चितकालीन प्रतीक्षा से बचाने के लिए एक टाइमआउट।
एक बार स्टेटस Ready हो जाने पर, API प्रतिक्रिया में आउटपुट इमेज का साइन किया हुआ URL होता है। हम अपनी पहले वाली url_to_pil() हेल्पर फ़ंक्शन का उपयोग करके उस इमेज को डाउनलोड करते हैं और इसे PIL इमेज के रूप में लौटाते हैं।
अगले चरण में, हम सेशन हिस्ट्री लागू करेंगे ताकि उपयोगकर्ता किसी भी जनरेटेड या एडिटेड आउटपुट पर वापस जा सकें।
चरण 5: हिस्ट्री जोड़ना
इस बिंदु पर, UI बनाने से पहले हमें अंतिम हिस्से के रूप में एक हल्का-फुल्का सेशन मेमोरी लेयर चाहिए ताकि उपयोगकर्ता पिछले आउटपुट पर वापस जा सकें। हम Gradio की दो state ऑब्जेक्ट्स का उपयोग करके हिस्ट्री लागू करते हैं:
base_img_stateवर्तमान कार्यरत इमेज को संग्रहीत करता है (वह इमेज जिस पर भविष्य के एडिट लागू होंगे)।history_stateहर जनरेटेड या एडिटेड संस्करण को डिक्शनरीज़ की सूची के रूप में संग्रहीत करता है, जिनमें प्रत्येक में एक इमेज और एक छोटा लेबल होता है।
def update_history(history):
choices = [f"{i}: {h['label']}" for i, h in enumerate(history or [])]
return gr.update(choices=choices, value=choices[-1] if choices else None)
def on_generate(prompt, history):
img = local_generate(prompt)
new_history = list(history or [])
new_history.append({"img": img, "label": "Generated Base"})
return img, img, new_history, update_history(new_history), "Base image generated."
def on_edit(edit_prompt, ref2, ref3, ref4, base_img, history):
if base_img is None:
raise gr.Error("Please generate a base image first.")
refs = [r.convert("RGB") for r in (ref2, ref3, ref4) if r is not None]
out = bfl_edit(edit_prompt, base_img, refs)
new_history = list(history or [])
new_history.append({"img": out, "label": f"Edit: {edit_prompt[:20]}..."})
return out, out, new_history, update_history(new_history), "Edit successful."
def on_load(choice, history):
if not history or not choice:
return None, None, "No history to load."
idx = int(choice.split(":")[0])
img = history[idx]["img"]
return img, img, f"Loaded entry #{idx}."
def on_clear():
return None, None, [], gr.update(choices=[], value=None), "Cleared everything."
ऊपर दिए गए फ़ंक्शंस हमारे डेमो में इमेज हिस्ट्री बनाए रखने के लिए मुख्य लॉजिक बनाते हैं:
update_history()फ़ंक्शन सेशन हिस्ट्री को ड्रॉपडाउन में फ़ॉर्मेट करता है। प्रत्येक एंट्री को उसके इंडेक्स और छोटे विवरण के साथ लेबल किया जाता है, और ड्रॉपडाउन डिफ़ॉल्ट रूप से स्वतः नवीनतम आइटम का चयन करता है। इससे UI बिना मैनुअल रिफ्रेश लॉजिक के सिंक में रहता है।on_generate()कॉलबैक प्रारंभिक बेस इमेज बनाने के लिएlocal_generate()चलाता है। फिर यह परिणाम को हिस्ट्री में{"img": img, "label": "Generated Base"}के रूप में जोड़ता है। फ़ंक्शन इमेज और अपडेटेड हिस्ट्री स्टेट दोनों लौटाता है, साथ ही एक ड्रॉपडाउन अपडेट ताकि नई एंट्री तुरंत दिखाई दे।on_edit()कॉलबैक समान है, लेकिन यहbfl_edit()को कॉल करता है। यह वर्तमान कार्यरत इमेज और कुछ वैकल्पिक रेफरेंस इमेज लेता है, API के माध्यम से एडिट लागू करता है, और आउटपुट को हिस्ट्री में जोड़ता है। यह एडिटेड आउटपुट को नएbase_img_stateके रूप में भी लौटाता है, यानी भविष्य के एडिट्स सबसे हालिया इमेज पर लागू होंगे जब तक उपयोगकर्ता स्पष्ट रूप से पुरानी वर्ज़न लोड न करे।on_load()कॉलबैक चयनित ड्रॉपडाउन एंट्री को पार्स करता है,history_stateसे संबंधित इमेज प्राप्त करता है, और उस इमेज को फिर से सक्रिय कार्यरत इमेज बना देता है। इससे उपयोगकर्ता किसी भी पिछले चेकपॉइंट से अपने एडिट्स की शाखा बना सकते हैं।- अंत में,
on_clear()फ़ंक्शन सब कुछ रीसेट करता है। यह आउटपुट को साफ करता है, बेस इमेज स्टेट को साफ करता है, हिस्ट्री सूची रीसेट करता है और ड्रॉपडाउन विकल्पों को खाली कर देता है।
आइए इन फ़ंक्शंस को दो टेक्स्टबॉक्स, वैकल्पिक रेफरेंस अपलोड और एक हिस्ट्री वर्कफ़्लो वाली Gradio इंटरफ़ेस में वायर करें।
चरण 6: Gradio UI
यह चरण हमारी जेनरेशन, एडिटिंग और हिस्ट्री लॉजिक को एक सरल Gradio इंटरफ़ेस से जोड़ता है। इंटरफ़ेस gr.Blocks के साथ बनाया गया है, जो हमें लेआउट पर सूक्ष्म नियंत्रण देता है।
with gr.Blocks() as demo:
gr.Markdown("## FLUX.2 Klein: Generate & Edit Images")
with gr.Row():
with gr.Column(scale=1):
gen_prompt = gr.Textbox(label="1. Generate Base Image", placeholder="A young boy riding a scooter...")
gen_btn = gr.Button("Generate Base Image", variant="primary")
edit_prompt = gr.Textbox(label="2. Describe Edits", placeholder="Add the red hat and yellow glasses from the references...")
with gr.Accordion("Reference Images (Optional)", open=False):
r2 = gr.Image(label="Ref 1", type="pil")
r3 = gr.Image(label="Ref 2", type="pil")
r4 = gr.Image(label="Ref 3", type="pil")
edit_btn = gr.Button("Apply Edit", variant="secondary")
history_dd = gr.Dropdown(label="Session History", choices=[])
with gr.Row():
load_btn = gr.Button("Load Selected")
clear_btn = gr.Button("Clear All")
status = gr.Textbox(label="Status", interactive=False)
with gr.Column(scale=1):
output_view = gr.Image(label="Current Image", type="pil")
base_img_state = gr.State(None)
history_state = gr.State([])
gen_btn.click(
on_generate,
[gen_prompt, history_state],
[output_view, base_img_state, history_state, history_dd, status]
)
edit_btn.click(
on_edit,
[edit_prompt, r2, r3, r4, base_img_state, history_state],
[output_view, base_img_state, history_state, history_dd, status]
)
load_btn.click(
on_load,
[history_dd, history_state],
[output_view, base_img_state, status]
)
clear_btn.click(
on_clear,
None,
[output_view, base_img_state, history_state, history_dd, status]
)
demo.launch(share=True, inline=True, debug = True)
हम UI को दो कॉलम में व्यवस्थित करते हैं, ताकि बाएँ कॉलम में इनपुट्स और एक्शन्स हों, जबकि दाएँ कॉलम में वर्तमान इमेज दिखाई दे। यहाँ हम Gradio ऐप कैसे बनाते हैं:
- पहला टेक्स्टबॉक्स जेनरेशन प्रॉम्प्ट लेता है, और Generate Base Image बटन
on_generate()फ़ंक्शन को ट्रिगर करता है। यह कॉलबैक स्थानीय जनरेशन चलाता है, आउटपुट को हिस्ट्री में सेव करता है, और प्रदर्शित इमेज तथाbase_img_stateमें संग्रहीत वर्तमान कार्यरत इमेज—दोनों को अपडेट करता है। - दूसरा टेक्स्टबॉक्स एडिट निर्देश प्रॉम्प्ट लेता है। जब उपयोगकर्ता Apply Edit पर क्लिक करता है, तो हम
on_edit()फ़ंक्शन को कॉल करते हैं, जो वर्तमान कार्यरत इमेज को बेस इमेज के रूप में उपयोग करता है और एडिटेड आउटपुट लौटाता है। एडिटेड आउटपुट को हिस्ट्री में भी जोड़ा जाता है और यह अगले एडिट्स के लिए नई कार्यरत इमेज बन जाता है। - वर्कफ़्लो को सेशन-अवेयर बनाने के लिए, हम Session History ड्रॉपडाउन भी शामिल करते हैं ताकि प्रत्येक एंट्री इमेज के एक सहेजे गए संस्करण के अनुरूप हो। Load Selected बटन
on_load()को ट्रिगर करता है, जो चुनी हुई हिस्ट्री इमेज को पुनर्स्थापित करता है और उसे फिर से वर्तमान कार्यरत इमेज के रूप में सेट करता है। - अंत में, Clear All बटन
on_clear()फ़ंक्शन के माध्यम से सब कुछ रीसेट करता है, जिसमें आउटपुट डिस्प्ले, बेस इमेज स्टेट और संग्रहीत हिस्ट्री शामिल हैं।
निम्नलिखित दो Gradio State ऑब्जेक्ट्स सब कुछ सुसंगत बनाए रखते हैं:
base_img_stateसुनिश्चित करता है कि हर एडिट सही इमेज पर लागू हो।history_stateरीप्ले और ब्रांचिंग के लिए आउटपुट्स की पूरी टाइमलाइन संग्रहीत करता है।
अंत में, demo.launch() Colab में ऐप लॉन्च करता है, एक शेयर करने योग्य लिंक प्रदान करता है, इसे इनलाइन रेंडर करता है, और डेवलपमेंट के दौरान समस्याओं का निदान करने में मदद के लिए डिबग लॉग सक्षम करता है।
FLUX.2 Klein उदाहरण और टिप्पणियाँ
यह समझने के लिए कि FLUX.2 Klein व्यवहार में कैसा काम करता है, मैंने अंतिम Generate and Edit ऐप का उपयोग करके छोटे-छोटे प्रयोगों का एक सेट चलाया। मैंने तीन मुख्य इंटरैक्शन पैटर्न का परीक्षण किया: बेस इमेज जनरेशन, केवल प्रॉम्प्ट-आधारित एडिटिंग, और एक या अधिक इमेज के साथ रेफरेंस-गाइडेड एडिटिंग। मैंने सेशन हिस्ट्री वर्कफ़्लो को भी मान्य किया ताकि यह पुष्टि हो सके कि मैं किसी भी पिछले आउटपुट को रिस्टोर कर सकता हूँ और वहीं से एडिटिंग जारी रख सकता हूँ।
इमेज जनरेशन
मैंने एक सरल जेनरेशन प्रॉम्प्ट के साथ एक साफ़-सुथरी बेस इमेज बनाने से शुरुआत की। मॉडल ने सुसंगत लाइटिंग, तेज़ चेहरे के विवरण और स्थिर सीन लेआउट के साथ एक सुसंगत सब्जेक्ट उत्पन्न किया। आउटपुट बेस इमेज दोबारा जनरेशन के बजाय बाद के संशोधनों के लिए मजबूत और उपयोगी लगी।

एकल रेफरेंस इमेज के साथ इमेज एडिटिंग
अगला, मैंने रंग स्रोत के रूप में एकल रेफरेंस इमेज का परीक्षण किया, और “ड्रेस का रंग रेफरेंस इमेज के रंग में बदलें।” जैसा एडिट निर्देश उपयोग किया। एडिट ने इच्छित रंग को सफलतापूर्वक ट्रांसफर किया, जबकि मूल सीन संरचना का अधिकांश हिस्सा संरक्षित रहा।
मेरे अवलोकन में, सिंगल रेफरेंस एडिट्स तब सबसे अच्छा काम करते हैं जब प्रॉम्प्ट संकीर्ण और सीमित हो। रंग ट्रांसफर और वार्डरोब री-कलरिंग विशेष रूप से विश्वसनीय हैं क्योंकि उन्हें बड़े ज्योमेट्री बदलावों की आवश्यकता नहीं होती। जब एडिट निर्देश एक ही एट्रिब्यूट पर केंद्रित रहता है, तो सब्जेक्ट की पहचान और बैकग्राउंड विवरण स्थिर रहते हैं।

केवल प्रॉम्प्ट के साथ इमेज एडिटिंग
फिर मैंने “बैकग्राउंड को बीच से बदलें।” जैसे सैमेन्टिक बदलाव के साथ केवल प्रॉम्प्ट-आधारित एडिटिंग आज़माई। मॉडल ने बैकग्राउंड सब्स्टीट्यूशन को साफ़-सुथरे तरीके से संभाला, जबकि सब्जेक्ट को लगभग सुसंगत रखा।
जब बैकग्राउंड बदलता है, तो परिणाम को फ़ोटो-रियलिस्टिक बनाए रखने के लिए मॉडल अक्सर रंग तापमान और शैडो तीव्रता को समायोजित करता है। यह आमतौर पर एक फीचर है, लेकिन इसका मतलब है कि एडिट की गई इमेज साधारण कट-एंड-पेस्ट की बजाय एक अलग फोटोशूट जैसी दिख सकती है।

पोज़ गाइडेंस
मैंने एक रेफरेंस इमेज का उपयोग करते हुए पोज़-आधारित एडिट का परीक्षण किया जो बॉडी पोज़िशनिंग को इंगित करती है, और “रेफरेंस इमेज से पोज़ मैच करें।” जैसा प्रॉम्प्ट दिया। परिणामी इमेज ने सब्जेक्ट का पोज़ शिफ्ट कर दिया जबकि समान पहचान और स्टाइलिंग को बरकरार रखा।
यह वह रेफरेंस इमेज है जिसका मैंने पोज़ गाइडेंस के लिए उपयोग किया:

पोज़ एडिट संभव हैं, लेकिन वे रंग एडिट की तुलना में अधिक संवेदनशील हैं। किसी भी पोज़ बदलाव से फैब्रिक ड्रेप, अंगों की प्लेसमेंट और कैमरा फ़्रेमिंग जैसे द्वितीयक परिवर्तन ट्रिगर हो सकते हैं। मुझे यह पोज़ ठीक करने के लिए कुछ प्रयोग करने पड़े, और यह अभी भी पैर की प्लेसमेंट के साथ संघर्ष कर रहा था।

एकाधिक रेफरेंस इमेज के साथ इमेज एडिटिंग
अंत में, मैंने कई इनपुट्स—जैसे एक कलर पैलेट रेफरेंस—और एक एडिट प्रॉम्प्ट का उपयोग करते हुए मल्टी-रेफरेंस एडिट्स का परीक्षण किया, जो स्पष्ट रूप से कहता है “केवल बैकग्राउंड रंगों को रेफरेंस इमेज के पैलेट का उपयोग करके बदलें। बैकग्राउंड को रेफरेंस इमेज से रिप्लेस न करें।”
मेरे लिए आश्चर्य की बात यह थी कि मल्टी-रेफरेंस एडिटि
ंग तब सबसे प्रभावी होती है जब प्रत्येक रेफरेंस इमेज की स्पष्ट भूमिका हो।
पैलेट रेफरेंस तब अच्छी तरह काम करते हैं जब प्रॉम्प्ट स्पष्ट रूप से केवल पैलेट कहता है और मॉडल को रेफरेंस कंटेंट को रिप्लेसमेंट के रूप में उपयोग करने के निर्देश देने से बचता है।
जब रेफरेंस अस्पष्ट होते हैं, तो मॉडल केवल रंग के बजाय टेक्सचर या लेआउट संकेत उधार ले सकता है। अपनी रन में, मैंने कुछ छोटे आर्टिफैक्ट्स देखे जहाँ रेफरेंस इमेज से मिलते-जुलते तत्व सूक्ष्म रूप से सीन में लीक हो गए, लेकिन समग्र परिणाम अभी भी मजबूत और दृश्य रूप से सुसंगत दिखा।

इस डेमो का एक व्यावहारिक लाभ यह है कि हर जनरेटेड और एडिटेड इमेज सेशन हिस्ट्री में सहेजी जाती है। आप किसी भी पिछली एंट्री को लोड कर सकते हैं और ठीक उसी चेकपॉइंट से एडिटिंग जारी रख सकते हैं। इससे प्रयोग बहुत तेज़ हो जाता है। आप किसी पहले के संस्करण से एडिट्स की ब्रांच बना सकते हैं, कई एडिट दिशाओं की तुलना कर सकते हैं और किसी अच्छे इंटरमीडिएट परिणाम को खोने से बच सकते हैं।
निष्कर्ष
इस ट्यूटोरियल में, हमने FLUX.2 Klein 4B का उपयोग करते हुए एक संपूर्ण जनरेशन और इमेज एडिटिंग वर्कफ़्लो बनाया। Diffusers के माध्यम से स्थानीय टेक्स्ट-टू-इमेज जनरेशन को Black Forest Labs के होस्टेड एडिटिंग API के साथ मिलाकर, हम एक इंटरैक्टिव इमेज एडिटर बना सके।
FLUX.2 Klein की कम-विलंबता, एकीकृत जनरेशन और एडिटिंग क्षमताएँ, और मल्टी-रेफरेंस सपोर्ट इसे इस तरह के इंटरैक्टिव वर्कफ़्लो के लिए विशेष रूप से उपयुक्त बनाते हैं। यहाँ से, आप ऐप को बैच एडिटिंग, पैरामीटर नियंत्रण, सेशन्स के बीच स्थायित्व, या यहाँ तक कि एक LLM-चालित एजेंट के साथ भी बढ़ा सकते हैं जो स्वतः एडिट्स प्रस्तावित करता है।
FLUX.2 Klein AQs
क्या मैं API हटाकर सब कुछ HF से कर सकता/सकती हूँ?
हाँ, लेकिन एडिटिंग लाइब्रेरी वर्ज़न और पोस्टप्रोसेसिंग पाथ्स के प्रति अधिक संवेदनशील हो सकती है। यदि आपका लक्ष्य एक विश्वसनीय एडिटिंग वर्कफ़्लो है, तो API अधिक सुरक्षित विकल्प है।
क्या मैं लोड की गई हिस्ट्री इमेज पर एडिट्स लागू करा सकता/सकती हूँ?
हाँ। वर्तमान डिज़ाइन में, हिस्ट्री लोड करना बेस इमेज स्टेट सेट करता है। इसके बाद की कोई भी एडिट उसी बेस पर लागू होगी।
क्या मैं हिस्ट्री को थंबनेल दिखाने तक बढ़ा सकता/सकती हूँ?
हाँ, आप ड्रॉपडाउन हिस्ट्री को गैलरी से बदल सकते हैं। स्टेट संरचना वही रहती है।
FLUX.2 Klein 4B को लोकली चलाने के लिए सिस्टम आवश्यकताएँ क्या हैं?
मॉडल को कुशलतापूर्वक चलाने के लिए, आपको लगभग 13GB VRAM वाला कंज्यूमर-ग्रेड GPU चाहिए। हालाँकि यह A100 जैसे हाई-एंड हार्डवेयर पर सबसे अच्छा प्रदर्शन करता है, इसे विशेष रूप से अधिक सुलभ GPUs (जैसे NVIDIA T4) पर थोड़ी अधिक लेटेंसी के साथ चलाने के लिए अनुकूलित किया गया है, जिससे यह पूर्ण FLUX फाउंडेशन मॉडलों की तुलना में कहीं अधिक हल्का हो जाता है।
क्या मैं FLUX.2 Klein को व्यावसायिक अनुप्रयोगों के लिए उपयोग कर सकता/सकती हूँ?
हाँ। FLUX.2 Klein 4B वेरिएंट Apache 2.0 लाइसेंस के तहत जारी किया गया है। यह एक उदार ओपन-सोर्स लाइसेंस है जो डेवलपर्स को व्यक्तिगत और व्यावसायिक सॉफ़्टवेयर दोनों के लिए मॉडल का उपयोग, संशोधन और वितरण करने की अनुमति देता है, बिना उन प्रतिबंधात्मक शर्तों के जो अक्सर अन्य मॉडल लाइसेंसों में पाई जाती हैं।
"Klein" अन्य FLUX.2 वेरिएंट से कैसे भिन्न है?
Klein एक डिस्टिल्ड मॉडल (4 बिलियन पैरामीटर) है जिसे गति और इंटरैक्टिविटी को प्राथमिकता देने के लिए बनाया गया है, न कि कच्चे लचीलेपन के लिए। जबकि FLUX.2 के बड़े "बेस" वेरिएंट गहरे फाइन-ट्यूनिंग के लिए अधिक उपयुक्त हैं, Klein "इंटरैक्टिव विज़ुअल इंटेलिजेंस" के लिए इंजीनियर्ड है, यानी यह तेज़ इन्फरेंस टाइम और रीयल-टाइम इटरेशन प्रदान करता है, जिससे यह रिस्पॉन्सिव यूज़र इंटरफेस और एडिटिंग टूल्स बनाने के लिए बेहतर विकल्प बनता है।
मैं एमएल (Gen AI) में Google Developers Expert, Kaggle 3x Expert, और Women Techmakers एंबेसडर हूँ, तथा तकनीक क्षेत्र में 3+ वर्षों का अनुभव रखती हूँ। मैंने 2020 में एक हेल्थ-टेक स्टार्टअप की सह-स्थापना की और वर्तमान में Georgia Tech से कंप्यूटर विज्ञान में मास्टर कर रही हूँ, जिसमें मेरा विशेषज्ञता क्षेत्र मशीन लर्निंग है।
