Z-Image Turbo: Configuración local y entrenamiento
Aprende a ejecutar Z-Image Turbo localmente, crear flujos de img2img e inpainting en ComfyUI y entrenar LoRAs de personajes con el adaptador de ostris.
On this page
Z-Image Turbo: Configuración local y entrenamiento
TL;DR
- Ejecuta Z-Image Turbo localmente con 6B de parámetros, inferencia de 8 pasos y latencia de menos de un segundo en 16 GB de VRAM; instala con
pip install git+https://github.com/huggingface/diffusersy cargaTongyi-MAI/Z-Image-Turboen bfloat16. - Crea flujos ligeros de img2img y inpainting en ComfyUI usando
ImageScaleToMaxDimension,VAE Encode (for inpainting)yRepeat Latent Batch, sin ControlNet; mantén el denoise entre 0.75–0.90 para img2img. - Entrena LoRAs de personajes con el ostris zimage_turbo_training_adapter_v2 (324 MB) en AI Toolkit: 3,000 pasos, rank 16, lr 1e-4, AdamW8bit, cubos de resolución múltiple (512/768/1024), subtítulos de una sola palabra; unos 15–22 min en RTX 5090, 8–12 h en RTX 4090.
Z-Image Turbo es un modelo distillado de 6 mil millones de parámetros de Tongyi-MAI que genera imágenes en 8 NFEs (evaluaciones funcionales de número) mientras iguala o supera a competidores más grandes en benchmarks de calidad. Ocupa el #1 entre los modelos de código abierto en el leaderboard de Artificial Analysis y renderiza texto bilingüe chino/inglés nativamente. Esta guía cubre la inferencia local, los flujos de img2img y inpainting de ComfyUI que evitan ControlNet, y una receta reproducible de entrenamiento de LoRA usando el adaptador de desdistilación de ostris.
Configuración de inferencia local
pip install git+https://github.com/huggingface/diffusers
import torch
from diffusers import ZImagePipeline
pipe = ZImagePipeline.from_pretrained(
"Tongyi-MAI/Z-Image-Turbo",
torch_dtype=torch.bfloat16,
).to("cuda")
prompt = "Young woman in red Hanfu, intricate embroidery, neon lightning-bolt lamp above palm, pagoda silhouette at night"
image = pipe(
prompt=prompt,
height=1024,
width=1024,
num_inference_steps=9,
guidance_scale=0.0,
generator=torch.Generator("cuda").manual_seed(42),
).images[0]
image.save("zimage_turbo.png")
Ajustes clave: guidance_scale=0.0, num_inference_steps=9 (produce 8 avanzamientos), bfloat16 en CUDA. El modelo entra en 16 GB de VRAM; habilita pipe.enable_model_cpu_offload() si necesitas correr con menos.
Flujo de img2img en ComfyUI (sin ControlNet)
La comunidad de Civitai converge sobre un grafo ligero de img2img que controla la resolución de entrada/salida sin ControlNet. Comienza desde la plantilla predeterminada ZiT Text to Image y reconecta como sigue.
Nodos que agregar
Nodo | Propósito ------|---------- Load Image | Entrada de imagen fuente ImageScaleToMaxDimension | Redimensiona a un borde máximo preservando la proporción VAE Encode | Codifica píxeles a latentes Repeat Latent Batch | Alinea el tamaño de lote para KSampler
Conexiones
Load VAE→ entradaVAEde VAE EncodeLoad Image→ entradaImagede ImageScaleToMaxDimensionImageScaleToMaxDimension→ entradaPixelsde VAE EncodeVAE Encode→ entradaSamplesde Repeat Latent BatchRepeat Latent Batch→ entradalatent_imagede KSampler
ImageScaleToMaxDimension por defecto en 512 de borde máximo; sube a 1024 o 1536 para mayor fidelidad. Los valores admitidos de upscale_method: area, lanczos, bilinear, nearest-exact, bicubic.
Zona dulce de denoise
Los tests de la comunidad reportan los mejores resultados de img2img con denoise 0.75–0.90 en el KSampler:
Denoise | Comportamiento | Source ---------|--------------|------- < 0.75 | Adherencia estricta a la fuente; solo cambios menores guiados por el prompt | https://civitai.com/articles/24793/lightweight-image-to-image-workflow-for-z-image-turbo-no-controlnet-wip 0.75 – 0.90 | Equilibrado: mantiene la composición, sigue el prompt fuertemente | https://civitai.com/articles/24793/lightweight-image-to-image-workflow-for-z-image-turbo-no-controlnet-wip
0.90 | Se desvía hacia texto a imagen puro; la influencia de la fuente se diluye | https://civitai.com/articles/24793/lightweight-image-to-image-workflow-for-z-image-turbo-no-controlnet-wip
Denoise bajo = más fidelidad a la fuente; alto = más adherencia al prompt. Comienza en 0.85 y ajusta.
Flujo de inpainting en ComfyUI
El inpainting usa el nodo VAE Encode (for inpainting), que acepta la imagen y una máscara. El mismo nodo ImageScaleToMaxDimension puede controlar la resolución.
Nodos que agregar
Nodo | Propósito ------|---------- Load Image | Imagen fuente + máscara (canal alfa o entrada de máscara aparte) VAE Encode (for inpainting) | Codifica píxeles + máscara a latentes Repeat Latent Batch | Alineación de lote para KSampler ImageScaleToMaxDimension (opcional) | Control de resolución
Conexiones
Load Image→Pixels+Mask→ VAE Encode (for inpainting)Load Image→Pixels→ ImageScaleToMaxDimension →image→ VAE Encode (for inpainting)Load VAE→vae→ VAE Encode (for inpainting)- VAE Encode (for inpainting) →
Latent→ Repeat Latent Batch →Samples - Repeat Latent Batch →
Latent→ KSampler →latent_image
Opcional: agrega el nodo Image Compare (vía ComfyUI Manager) para previewear image_a (entrada escalada) vs image_b (salida VAE Decode) lado a lado.
Entrenamiento de un LoRA de personaje con AI Toolkit
Z-Image Turbo es un modelo distillado; entrenar un LoRA directamente sobre él rompe la velocidad de 8 pasos ("Turbo Drift"). El ostris zimage_turbo_training_adapter_v2 lo resuelve: es un LoRA de desdistilación de 324 MB entrenado con miles de salidas de Z-Image Turbo a lr 1e-5. Entrenas tu LoRA encima de este adaptador y luego lo eliminas en inferencia; tu LoRA conserva la velocidad de 8 pasos.
Prerrequisitos
Item | Especificación | Source -----|---------------|------- GPU (NVIDIA) | Mínimo 12 GB VRAM, recomendado 24 GB | https://kawaiipromptlab.com/en/tutorials/lora-training-guide/ GPU (Apple Silicon) | Mínimo 32 GB unificados, recomendado 64 GB | https://kawaiipromptlab.com/en/tutorials/lora-training-guide/ Disco | 50 GB libres (100 GB recomendados) | https://github.com/ostris/ai-toolkit Python | 3.10+ | https://github.com/ostris/ai-toolkit PyTorch | 2.0+ (2.8+ para MPS) | https://github.com/ostris/ai-toolkit
Instalar AI Toolkit:
git clone https://github.com/ostris/ai-toolkit.git
cd ai-toolkit
git submodule update --init --recursive
pip install -r requirements.txt
Descargar el adaptador:
huggingface-cli download ostris/zimage_turbo_training_adapter zimage_turbo_training_adapter_v2.safetensors
# Colocar en tu carpeta de pesos, p.ej. ./weights/zimage_turbo_training_adapter_v2.safetensors
Preparación del dataset
- LoRA de personaje: 70–80 imágenes para calidad alta (textura de piel), 15+ para una prueba funcional
- LoRA de estilo: 30–120 imágenes (punto óptimo ~45)
- Resolución: 1024×1024 recomendada; 512 funciona pero con menor fidelidad
- Composición: 40–50% acercamientos, 30–40% planos medios, 10–20% cuerpo completo
- Subtítulos: trigger de una sola palabra por imagen (p. ej.
sksoohwx). No escribas oraciones descriptivas; el modelo ya sabe "clothes", "background", etc. El sobre-subtítulo causa rostros "mushy" y pérdida de detalle.
Diseño de carpetas:
datasets/
└── my_character/
├── img_001.jpg
├── img_001.txt # contiene solo: sks
├── img_002.jpg
├── img_002.txt # contiene solo: sks
└── ...
Configuración de entrenamiento (YAML)
Guarda como config/my_zimage_lora.yaml:
job: extension
config:
name: "my_zimage_lora_v1"
process:
- type: "sd_trainer"
training_folder: "output"
device: "cuda:0"
trigger_word: "sks"
network:
type: "lora"
linear: 16
linear_alpha: 16
save:
dtype: "float16"
save_every: 250
max_step_saves_to_keep: 4
datasets:
- folder_path: "/path/to/datasets/my_character"
caption_ext: "txt"
caption_dropout_rate: 0.05
cache_latents_to_disk: true
resolution: [512, 768, 1024]
train:
batch_size: 1
steps: 3000
gradient_accumulation_steps: 1
train_unet: true
train_text_encoder: false
gradient_checkpointing: true
noise_scheduler: "flowmatch"
optimizer: "adamw8bit"
lr: 1e-4
ema_config:
use_ema: true
ema_decay: 0.99
dtype: "bf16"
model:
name_or_path: "Tongyi-MAI/Z-Image-Turbo"
arch: "zimage"
assistant_lora_path: "./weights/zimage_turbo_training_adapter_v2.safetensors"
quantize: true
sample:
sampler: "flowmatch"
sample_every: 250
width: 1024
height: 1024
prompts:
- "sks, portrait photo, natural lighting"
seed: 42
guidance_scale: 1
sample_steps: 8
Ajustes para Apple Silicon (MPS): cambia device: "mps:0", optimizer: "adamw" (adamw8bit solo es CUDA), quantize: false, y agrega num_workers: 0 bajo datasets.
Ejecutar entrenamiento
cd ai-toolkit
python run.py config/my_zimage_lora.yaml
Tiempos de pared esperados (3,000 pasos):
Hardware | Tiempo | Source ---------|--------|------- RTX 5090 (RunPod) | ~15–22 min ($0.89/hr) | https://x.com/ostrisai/status/1995504226295009558 RTX 4090 | ~8–12 hours | https://kawaiipromptlab.com/en/tutorials/lora-training-guide/ Apple M4 Pro (64 GB) | ~21 hours | https://kawaiipromptlab.com/en/tutorials/lora-training-guide/
Monitorea la decayencia de pérdida y las imágenes de muestra cada 250 pasos. Para temprano si la identidad se estabiliza; extiende a 5,000 pasos solo con datos y subtítulos limpios.
Inferencia con el LoRA entrenado
ComfyUI: coloca my_zimage_lora_v1.safetensors en ComfyUI/models/loras/, agrega un nodo Load LoRA entre el cargador del modelo y KSampler, con strength 0.8–1.0.
Python (Diffusers):
from diffusers import ZImagePipeline
import torch
pipe = ZImagePipeline.from_pretrained(
"Tongyi-MAI/Z-Image-Turbo",
torch_dtype=torch.bfloat16,
).to("cuda")
pipe.load_lora_weights("./output/my_zimage_lora_v1.safetensors", adapter_name="character")
pipe.set_adapters(["character"], adapter_weights=[0.9])
image = pipe(
prompt="sks, portrait photo, natural lighting, 85mm lens",
num_inference_steps=9,
guidance_scale=0.0,
width=1024,
height=1024,
generator=torch.Generator("cuda").manual_seed(42),
).images[0]
image.save("lora_result.png")
Crítico: no cargues el adaptador de entrenamiento en inferencia. Tu LoRA solo conserva la velocidad distillada de 8 pasos.
Errores comunes y soluciones
Síntoma | Causa probable | Solución | Source
|---------|--------------|-----|--------
LoRA sin efecto visible | El trigger falta o está mal escrito en el prompt | Usa el token exacto de los subtítulos (p. ej., sks) | https://huggingface.co/blog/content-and-code/training-a-lora-for-z-image-turbo Rostros derretidos / "mushy" | Sobre-subtítulo (oraciones descriptivas) | Cambia a subtítulos de una sola palabra; vuelve a entrenar | https://huggingface.co/blog/content-and-code/training-a-lora-for-z-image-turbo Falta de VRAM en tarjetas de 12–16 GB | quantize: true no activado, o lote > 1 | Activa la cuantización, batch_size: 1, gradient_checkpointing: true | https://github.com/ostris/ai-toolkit Entrenamiento se detiene en el paso 0 | Ruta del adaptador incorrecta o archivo faltante | Verifica que assistant_lora_path apunte a zimage_turbo_training_adapter_v2.safetensors | https://huggingface.co/ostris/zimage_turbo_training_adapter Las imágenes generadas ignoran el prompt | Denoise demasiado bajo (< 0.7) en img2img | Sube el denoise de KSampler a 0.75–0.90 | https://civitai.com/articles/24793/lightweight-image-to-image-workflow-for-z-image-turbo-no-controlnet-wip El inpainting ignora la máscara | Máscara no conectada a VAE Encode (for inpainting) | Conecta Load Image → Mask → VAE Encode (for inpainting) | https://civitai.com/articles/24764/simple-inpainting-workflow-for-z-image-turbo-comfyui Archivo de LoRA demasiado grande (> 500 MB) | Rank demasiado alto (p. ej., 64) | Usa linear: 16, linear_alpha: 16 | https://huggingface.co/blog/content-and-code/training-a-lora-for-z-image-turbo Adaptador de entrenamiento no descargado | Se usó la URL v1 en lugar de v2 | Descarga zimage_turbo_training_adapter_v2.safetensors (324 MB) del repo de ostris | https://huggingface.co/ostris/zimage_turbo_training_adapter
FAQ
¿Cuántas imágenes necesito para un LoRA de personaje? 15+ imágenes y más de 1,000 pasos para una prueba funcional; 70–80 imágenes a 1024×1024 para calidad de producción que reproduzca textura de piel.
¿Qué valor de denoise debo usar para img2img? Empieza en 0.85. Por debajo de 0.75 mantiene la fuente casi sin cambios; por encima de 0.90 se desvía hacia texto a imagen puro.
¿Necesito ControlNet para img2img o inpainting? No. Los flujos ligeros anteriores usan solo nodos nativos de ComfyUI (ImageScaleToMaxDimension, VAE Encode, Repeat Latent Batch) y igualan el control estilo ControlNet en la mayoría de los casos.
¿Por qué mi entrenamiento de LoRA genera artefactos después de 4,000+ pasos? El efecto de desdistilación del adaptador de entrenamiento se desgasta en ejecuciones largas. Quédate en 3,000 pasos a menos que tengas datos y subtítulos impecables; más allá de 5,000 pasos, el colapso de la desdistilación provoca artefactos.
¿Puedo entrenar en Apple Silicon? Sí. Usa device: mps:0, optimizer: adamw, quantize: false, num_workers: 0. Espera unas 21 horas para 3,000 pasos en M4 Pro de 64 GB.
¿A qué resolución debo entrenar? Cubos de resolución múltiple [512, 768, 1024] con 1024×1024 como objetivo. El cubo 512 es el tamaño de cubo de entrenamiento, no un downscale de tu dataset.
¿Es obligatorio fp32 (precisión completa)? Reportes de la comunidad dicen que los guardados en fp32 eliminan alucinaciones y mejoran la calidad a más de 5,000 pasos. Si la VRAM lo permite, mantén quantize: false y guarda en fp32; si no, bf16 con cuantización es el valor predeterminado práctico.
¿Cómo elimino el adaptador de entrenamiento en inferencia? Simplemente no lo cargues. Tu LoRA entrenado es el único peso extra que cargas sobre el modelo base Z-Image Turbo.
Guías relacionadas
- Conceptos básicos de ComfyUI para modelos de difusión
- Fundamentos de entrenamiento de LoRA
- Comparativa Z-Image vs Flux
- Hoja de trucos de alquiler de GPU en RunPod
- Selección de VAE para modelos de difusión