Spaces:
Running
Running
| import argparse | |
| import torch | |
| import os | |
| from transformers import AutoProcessor | |
| from models.qwen3_vl_transformers import Qwen3VLForConditionalGeneration | |
| from models.pipeline import generate_image, DEFAULT_TIMESTEPS | |
| def add_special_tokens(tokenizer): | |
| """Attach the special-token shortcuts that the pipeline relies on.""" | |
| tokenizer.boi_token = "<|boi_token|>" | |
| tokenizer.bor_token = "<|bor_token|>" | |
| tokenizer.eor_token = "<|eor_token|>" | |
| tokenizer.bot_token = "<|bot_token|>" | |
| tokenizer.tms_token = "<|tms_token|>" | |
| def get_tokenizer(processor): | |
| from transformers import PreTrainedTokenizerBase | |
| if isinstance(processor, PreTrainedTokenizerBase): | |
| return processor | |
| return processor.tokenizer | |
| def main(): | |
| p = argparse.ArgumentParser("Standalone Pixel-DiT inference") | |
| p.add_argument("--model_path", type=str, default = "/root/converted_models/HiDream-O1-Image", help="Path to huggingface model") | |
| p.add_argument("--prompt", type=str, default = "medium shot, eye-level, front view. A woman is seated in an ornate bedroom, illuminated by candlelight, with a calm and composed expression. The subject is a young woman with fair skin, light brown hair styled in an updo with loose tendrils framing her face, and blue eyes. She wears a cream-colored satin robe with delicate floral embroidery and lace trim along the neckline. Her ears are adorned with pearl drop earrings. She is seated on a bed with a dark, intricately carved wooden headboard. To her left, a wooden nightstand holds three lit white candles and a candelabra with multiple lit candles in the background. The bed is covered with patterned pillows and a dark, textured blanket. The walls are paneled with dark wood and feature a large, ornate tapestry with muted earth tones. The lighting creates soft highlights on her face and robe, with warm shadows cast across the room.") | |
| p.add_argument("--ref_images", nargs="*", default=[], help="Path to reference images.") | |
| p.add_argument( | |
| "--layout_bboxes", | |
| type=str, | |
| default=None, | |
| help=( | |
| "Layout boxes as a JSON string or JSON file path. " | |
| "Input order is xxyy relative coordinates: [[x1,x2,y1,y2], ...], " | |
| "[{\"bbox\": [x1,x2,y1,y2], \"text\": \"...\"}, ...], " | |
| "or {\"bboxes\": ...}. Example: [0.1,0.15,0.2,0.36]." | |
| ), | |
| ) | |
| p.add_argument("--output_image", type=str, default="output.png") | |
| p.add_argument("--height", type=int, default=2048) | |
| p.add_argument("--width", type=int, default=2048) | |
| p.add_argument("--model_type", type=str, default="dev", choices=["full", "dev"]) | |
| p.add_argument("--seed", type=int, default=42) | |
| p.add_argument("--shift", type=float, default=3.0) | |
| p.add_argument("--guidance_scale", type=float, default=5.0) | |
| p.add_argument("--noise_scale_start", type=float, default=8.0) | |
| p.add_argument("--noise_scale_end", type=float, default=8.0) | |
| p.add_argument("--noise_clip_std", type=float, default=8.0) | |
| p.add_argument( | |
| "--editing_scheduler", | |
| type=str, | |
| default="flow_match", | |
| choices=["flow_match", "flash"], | |
| help="Scheduler used for editing (exactly one reference image) when " | |
| "--model_type dev. Default: flow_match. Ignored for full model " | |
| "and for non-editing tasks.", | |
| ) | |
| p.add_argument( | |
| "--keep_original_aspect", | |
| action="store_true", | |
| help="When exactly one reference image is provided, resize it with " | |
| "max_size=2048 and use its dimensions for the target image " | |
| "(preserves the reference's aspect ratio).", | |
| ) | |
| args = p.parse_args() | |
| assert torch.cuda.is_available(), "CUDA is required for inference." | |
| print(f"[inference] Loading processor and model from {args.model_path}") | |
| processor = AutoProcessor.from_pretrained(args.model_path) | |
| # NOTE: torch_dtype = torch.float32 will generate more detailed images but with more memory usage | |
| model = Qwen3VLForConditionalGeneration.from_pretrained( | |
| args.model_path, torch_dtype=torch.float32, device_map="cuda" | |
| ).eval() | |
| os.makedirs(os.path.dirname(os.path.abspath(args.output_image)), exist_ok=True) | |
| tokenizer = get_tokenizer(processor) | |
| add_special_tokens(tokenizer) | |
| extra_kwargs = {} | |
| if args.model_type == "full": | |
| num_inference_steps = 50 | |
| guidance_scale = args.guidance_scale | |
| shift = args.shift | |
| timesteps_list = None | |
| scheduler_name = "default" | |
| else: | |
| is_editing = len(args.ref_images) == 1 | |
| if is_editing and args.editing_scheduler == "flow_match": | |
| num_inference_steps = 28 | |
| guidance_scale = 0.0 | |
| shift = 1.0 | |
| timesteps_list = DEFAULT_TIMESTEPS | |
| scheduler_name = "flow_match" | |
| else: | |
| num_inference_steps = 28 | |
| guidance_scale = 0.0 | |
| shift = 1.0 | |
| timesteps_list = DEFAULT_TIMESTEPS | |
| scheduler_name = "flash" | |
| extra_kwargs["noise_scale_start"] = args.noise_scale_start | |
| extra_kwargs["noise_scale_end"] = args.noise_scale_end | |
| extra_kwargs["noise_clip_std"] = args.noise_clip_std | |
| image = generate_image( | |
| model=model, | |
| processor=processor, | |
| prompt=args.prompt, | |
| ref_image_paths=args.ref_images, | |
| height=args.height, | |
| width=args.width, | |
| num_inference_steps=num_inference_steps, | |
| guidance_scale=guidance_scale, | |
| shift=shift, | |
| timesteps_list=timesteps_list, | |
| scheduler_name=scheduler_name, | |
| seed=args.seed, | |
| keep_original_aspect=args.keep_original_aspect, | |
| layout_bboxes = args.layout_bboxes, | |
| **extra_kwargs, | |
| ) | |
| image.save(args.output_image) | |
| print(f"[inference] Saved -> {args.output_image}") | |
| if __name__ == "__main__": | |
| main() | |