ns2agi/notion-avatar-qwen-image-edit-2509-lora
Notion-style avatar LoRA for Qwen-Image-Edit-2509
Turns a webcam photo into a black-on-white, Notion-style line avatar of the person in front of the camera. North Star built it for a booth where a Dobot Magician pen plotter draws each visitor's avatar on a card, so the output favours clean, closed strokes over shading.
Files
Both are rank-16 LoRAs on the transformer only, trained at 512 px with ostris ai-toolkit (AdamW 8-bit, learning rate 1e-4, batch 1, fp8 base). They render fine at 1024 px.
Usage
import torch
from diffusers import QwenImageEditPlusPipeline
from PIL import Image
pipe = QwenImageEditPlusPipeline.from_pretrained(
"Qwen/Qwen-Image-Edit-2509", torch_dtype=torch.bfloat16
).to("cuda")
pipe.load_lora_weights(
"ns2agi/notion-avatar-qwen-image-edit-2509-lora",
weight_name="e2_real_synth.safetensors",
adapter_name="style",
)
photo = Image.open("visitor.jpg").convert("RGB") # square crop around the face works best
avatar = pipe(
image=[photo],
prompt="Redraw this person as a Notion-style line avatar",
negative_prompt=" ",
num_inference_steps=30,
true_cfg_scale=4.0,
height=1024,
width=1024,
).images[0]
avatar.save("avatar.png")For a booth, stack the Lightning 8-step LoRA and drop to 8 steps with true_cfg_scale=1.0. On an A100 80 GB that is 12 to 14 seconds per avatar in bf16 with no visible loss against 30 steps:
pipe.load_lora_weights(
"lightx2v/Qwen-Image-Lightning",
weight_name="Qwen-Image-Edit-2509/Qwen-Image-Edit-2509-Lightning-8steps-V1.0-bf16.safetensors",
adapter_name="lightning",
)
pipe.set_adapters(["style", "lightning"], adapter_weights=[1.0, 1.0])The caption is fixed. The LoRA learned the mapping from the image pair, so the text carries little information and other prompts are not needed.
What to expect
- Works on photos of one person, head and shoulders, in any lighting, including near darkness, strict profiles, glasses, face masks, hats, hijabs, helmets and heavy makeup.
- Draws everyone in frame at their true scale. Crop to the nearest face before inference when the photo has several people or a wide framing.
- Full-body or distant subjects come out as small figures, so crop to the face before running the model.
- Not a person: a dog becomes a line-art dog, a marble bust stays a bust.
Training data
The bulk of the training set is 600 synthetic portraits generated with RealVisXL 5.0 from templated prompts covering age, heritage, hair, facial hair, glasses, expression, angle, clothing, venue and lighting, paired with targets rendered by gpt-image-2.5-sunburst using the booth's production prompt and style sheet. The training set is not distributed.
Training targets came from OpenAI image outputs, which OpenAI's terms allow the customer to use. The base model and the Lightning LoRA are Apache-2.0; this LoRA is released under Apache-2.0 as well.
Reference server
The booth serves this LoRA from Modal (A100 80 GB, scale to zero after 15 idle minutes, nearest-face crop, Lightning 8-step). The deploy file lives in the magician repository under deploy/modal_avatar.py.
Credits
Trained by North Star (ns2agi.com) in September 2026 on a Scaleway L40S. Base model by the Qwen team, Lightning LoRA by lightx2v.
