Qwen-Image-2.1 é o modelo de imagem de pesos abertos que a Alibaba lançou em 20 de setembro de 2026: um gerador de 7 bilhões de parâmetros que lida com texto para imagem, edição com até 10 imagens de referência e saída transparente nativa (RGBA). Este guia leva você do pip install a um endpoint HTTP funcional. Ele cobre os quatro caminhos de código de referência do README do GitHub, as configurações importantes, um pequeno wrapper FastAPI para que o modelo possa ser chamado como qualquer outra API de imagem, e como testar esse endpoint no Apidog para que as alterações de prompt e as atualizações do modelo não quebrem seu aplicativo.
Se você quiser o contexto primeiro, O que é Qwen-Image-2.1 aborda a arquitetura e a licença. A versão resumida da licença: uso apenas para pesquisa e não comercial, a menos que você obtenha um acordo comercial separado da Qwen. Tudo abaixo é adequado para avaliação.
Antes de começar
| Requisito | Detalhe |
|---|---|
| Pacotes Python | torch>=2.4.0, transformers>=5.17, diffusers do main do GitHub, accelerate, pillow |
| Classe do Pipeline | QwenImage21Pipeline (uma classe para geração e edição) |
| Pesos | Qwen/Qwen-Image-2.1, bf16 safetensors |
| GPU | Não especificado pela Qwen; o código de referência visa um dispositivo CUDA em bfloat16, com enable_model_cpu_offload() como fallback |
| Saída padrão | 2048 x 2048; 40 passos de inferência |
| Opcional | Modelos de reescrita de prompt Qwen-Image-2.1-PE-T2I / PE-I2I |
Instalar:
pip install "torch>=2.4.0" "transformers>=5.17" accelerate pillow
pip install git+https://github.com/huggingface/diffusers
A integração dos diffusers foi lançada em um PR dedicado no dia do lançamento, então uma versão PyPI anterior a 20 de setembro não terá a classe de pipeline.
Passo 1: texto para imagem
import torch
from diffusers import QwenImage21Pipeline
pipe = QwenImage21Pipeline.from_pretrained(
"Qwen/Qwen-Image-2.1", torch_dtype=torch.bfloat16
).to("cuda")
image = pipe(
prompt='A neon shop sign that reads "QWEN IMAGE 2.1", rainy night, reflections on wet pavement',
num_inference_steps=40,
generator=torch.Generator("cuda").manual_seed(42),
).images[0]
image.save("t2i_example.png")
Duas coisas a serem observadas. O prompt coloca o texto da placa entre aspas; a renderização de texto da Qwen é a razão pela qual as pessoas escolhem esta linha de modelos, e citar a string literal é a convenção de lançamentos anteriores. E a seed é explícita. Mantenha-a assim em cada solicitação que você pretende testar, porque uma seed fixa é o que torna um endpoint de imagem reproduzível o suficiente para ser verificado.
Passe width e height da tabela de suporte quando precisar de uma saída não quadrada:
| Proporção | Tamanho |
|---|---|
| 1:1 | 2048 x 2048 |
| 4:3 / 3:4 | 2400 x 1792 / 1792 x 2400 |
| 3:2 / 2:3 | 2528 x 1696 / 1696 x 2528 |
| 16:9 / 9:16 | 2752 x 1536 / 1536 x 2752 |
Passo 2: saída transparente
A transparência é impulsionada pelo prompt. A fraseologia recomendada no README é literal, então use-a:
image = pipe(
prompt=(
"This is an RGBA image with transparency. A cute cartoon dragon sticker. "
"The image has alpha channel and the background is transparent."
),
num_inference_steps=40,
generator=torch.Generator("cuda").manual_seed(42),
).images[0]
image.save("transparent_example.png")
Verifique o resultado em vez de confiar nele:
assert image.mode == "RGBA", image.mode
alpha = image.getchannel("A")
print("transparent pixels:", sum(1 for p in alpha.getdata() if p == 0))
Essa asserção é o primeiro teste que você irá portar para o Apidog mais tarde. Um modelo que retorna RGB silenciosamente quando você pediu RGBA é um bug que seus usuários encontrarão antes de você.
Passo 3: edição, com uma imagem ou até dez
O mesmo pipeline edita quando você passa image:
from PIL import Image
input_image = Image.open("input.png")
edited = pipe(
prompt="Change the background to a sunset beach",
image=input_image,
num_inference_steps=40,
generator=torch.Generator("cuda").manual_seed(42),
).images[0]
edited.save("edit_example.png")
Para múltiplas referências, passe uma lista (o limite do post de lançamento é 10):
refs = [Image.open(f"ref_{i}.png") for i in range(3)]
result = pipe(
prompt="These three characters are sitting around a campfire in a forest",
image=refs,
num_inference_steps=40,
generator=torch.Generator("cuda").manual_seed(42),
).images[0]
result.save("multi_ref_example.png")
A edição local funciona de três maneiras no post de lançamento: círculos coloridos que você referencia por cor no prompt, anotações pintadas, ou a imagem original intocada mais uma imagem de máscara separada passada como duas entradas. O README não inclui um exemplo de máscara dedicado, então a forma de duas entradas é a primeira a ser experimentada: image=[original, mask] com um prompt que descreve o que vai na região mascarada [VERIFICAR contra o README assim que um exemplo de máscara for incluído].
A edição também é onde o trabalho de velocidade do 2.1 se destaca. As imagens de referência e a instrução são estáticas em todas as etapas de denoising, então o modelo calcula seu cache de chave-valor uma vez e o reutiliza. Dez referências custam visivelmente menos do que dez vezes uma.
Passo 4: ajuste-o à sua GPU
A Qwen não publicou os números de VRAM. Se o pipeline bf16 não couber, o README oferece:
pipe = QwenImage21Pipeline.from_pretrained("Qwen/Qwen-Image-2.1", torch_dtype=torch.bfloat16)
pipe.enable_model_cpu_offload()
Para servir, o README aponta para vLLM-Omni (com FP8), SGLang e LightX2V. O ComfyUI tem suporte nativo com um fluxo de trabalho de template se você preferir não escrever Python. E se você não tem GPU, as opções gratuitas cobrem a demo hospedada e o Qwen Chat.
Passo 5: encapsule-o como uma API HTTP
O código do aplicativo não deve importar diffusers. Coloque o pipeline atrás de um pequeno serviço para que ele tenha um contrato que você possa versionar, simular e testar. Este wrapper FastAPI tem cerca de 40 linhas e retorna bytes PNG:
# server.py
import io, torch
from fastapi import FastAPI, UploadFile, File, Form
from fastapi.responses import Response
from PIL import Image
from diffusers import QwenImage21Pipeline
app = FastAPI()
pipe = QwenImage21Pipeline.from_pretrained(
"Qwen/Qwen-Image-2.1", torch_dtype=torch.bfloat16
).to("cuda")
SIZES = {"1:1": (2048, 2048), "16:9": (2752, 1536), "9:16": (1536, 2752)}
@app.post("/v1/images")
async def generate(
prompt: str = Form(...),
aspect: str = Form("1:1"),
transparent: bool = Form(False),
seed: int = Form(42),
steps: int = Form(40),
references: list[UploadFile] = File(default=[]),
):
if transparent and not prompt.startswith("This is an RGBA image"):
prompt = ("This is an RGBA image with transparency. " + prompt +
" The image has alpha channel and the background is transparent.")
refs = [Image.open(io.BytesIO(await f.read())) for f in references[:10]]
w, h = SIZES.get(aspect, SIZES["1:1"])
kwargs = dict(prompt=prompt, num_inference_steps=steps,
generator=torch.Generator("cuda").manual_seed(seed))
if refs:
kwargs["image"] = refs if len(refs) > 1 else refs[0]
else:
kwargs.update(width=w, height=h)
image = pipe(**kwargs).images[0]
buf = io.BytesIO()
image.save(buf, format="PNG")
return Response(buf.getvalue(), media_type="image/png",
headers={"X-Image-Mode": image.mode, "X-Seed": str(seed)})
Execute-o com uvicorn server:app --port 8000. Os dois cabeçalhos de resposta, X-Image-Mode e X-Seed, existem para que um teste possa verificar a transparência e a reprodutibilidade sem decodificar o PNG. Essa é a única escolha específica do produto no wrapper; o resto é um endpoint multipart simples.
Passo 6: teste o endpoint no Apidog
Agora é uma API, e a mesma disciplina que você aplicaria à API gpt-image-2.5 ou à API Nano Banana 2 se aplica aqui. No Apidog:
- Crie o endpoint como
POST {{base_url}}/v1/imagescom um corpo multipart:prompt,aspect,transparent,seed,steps, e um campo de arquivoreferencesrepetível. Coloquebase_urlem um ambiente para que a mesma coleção aponte para seu laptop, para a máquina com GPU ou para um mock. - Envie uma solicitação de texto para imagem com
seed=42e o prompt da placa de néon. Confirme200,Content-Type: image/pngeX-Image-Mode: RGB. - Adicione asserções no pós-processador: o status é 200,
X-Image-Modeé igual aRGBAquandotransparent=true, o tamanho do corpo da resposta está acima de um limite (um PNG de 2K que retorna com 2 KB é uma imagem em branco), eX-Seedecoa o que você enviou. - Envie o caso de transparência e uma edição de três referências da mesma forma, anexando as imagens no campo de arquivo. Salve cada um como um caso de teste.
- Execute-os como um cenário de teste em uma programação ou em CI. Quando você trocar por uma build quantizada ou um futuro 2.2, o conjunto de testes informará em minutos se a transparência ainda funciona e se a seed ainda reproduz.
- Simule-o (Mock it) enquanto a GPU está ocupada. O mock inteligente do Apidog retorna um PNG pré-definido para o mesmo contrato, para que o frontend continue sendo construído.
Como o Apidog também gera a especificação OpenAPI e a documentação a partir do endpoint que você definiu, o contrato do wrapper se torna compartilhável no momento em que funciona. Baixe o Apidog e importe o endpoint acima para começar.
Opcional: reescrita de prompt com PE-T2I
O Space de demonstração transforma solicitações de uma linha em prompts estruturados longos usando Qwen-Image-2.1-PE-T2I, um Qwen3.5-VL 9B ajustado que retorna JSON com um prompt expandido em inglês e uma proporção recomendada. Execute-o como um segundo serviço na frente de /v1/images, ou ignore-o e escreva prompts completos você mesmo. Se você adicioná-lo, teste-o separadamente: é uma API de texto com um contrato JSON, e um reescritor quebrado produz imagens ruins que parecem um bug do gerador.
FAQ
Um pipeline faz geração e edição? Sim. QwenImage21Pipeline gera quando chamado apenas com um prompt e edita quando você passa image (a única imagem PIL ou uma lista de até 10).
Como obtenho um PNG transparente? Comece o prompt com “This is an RGBA image with transparency” (Esta é uma imagem RGBA com transparência) e diga que o fundo é transparente. Verifique image.mode == "RGBA" no resultado.
Quais são as configurações recomendadas? 40 passos de inferência e bfloat16, de acordo com o README. Os valores de orientação não estão listados para o 2.1; versões anteriores do Qwen-Image usavam true_cfg_scale=4.0, então tente isso se as saídas parecerem sub-orientadas [VERIFICAR].
Posso usar isso em um produto comercial? Não sob a licença padrão. Qwen-Image-2.1 é distribuído sob a Licença de Pesquisa Qwen; o uso comercial requer uma licença separada da Qwen. Detalhes em O que é Qwen-Image-2.1.
Existe uma API hospedada em vez disso? Qwen Image 3.0 e 3.0 Pro são os modelos de imagem hospedados da Alibaba com precificação por imagem. A comparação 2.1 vs 3.0 aborda quando hospedar por conta própria e quando alugar.
Onde ir a seguir
Agora você tem quatro chamadas funcionando, um wrapper com um contrato estável e um conjunto de testes que verifica as duas propriedades mais importantes para este modelo: transparência e reprodutibilidade. Em seguida, decida se a licença de pesquisa se adequa ao seu uso, ou se a API 3.0 hospedada é a melhor opção, e mantenha ambos por trás da mesma coleção do Apidog para que a troca seja uma alteração na URL base, e não uma reescrita.
