Text Generation
Transformers
Safetensors
MiniMax H3
English
qwen3_5
image-text-to-text
prompt-expansion
text-to-image
fp4
sglang
conversational
8-bit precision
modelopt
Instructions to use MiniMaxAI/MiniMax-H3-Image-PE with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use MiniMaxAI/MiniMax-H3-Image-PE with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="MiniMaxAI/MiniMax-H3-Image-PE") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# pip install -U transformers accelerate # Load model directly from transformers import AutoProcessor, AutoModelForMultimodalLM processor = AutoProcessor.from_pretrained("MiniMaxAI/MiniMax-H3-Image-PE") model = AutoModelForMultimodalLM.from_pretrained("MiniMaxAI/MiniMax-H3-Image-PE", device_map="auto") messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] inputs = processor.apply_chat_template( messages, add_generation_prompt=True, tokenize=True, return_dict=True, return_tensors="pt", ).to(model.device) outputs = model.generate(**inputs, max_new_tokens=256) print(processor.decode(outputs[0][inputs["input_ids"].shape[-1]:])) - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use MiniMaxAI/MiniMax-H3-Image-PE with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "MiniMaxAI/MiniMax-H3-Image-PE" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "MiniMaxAI/MiniMax-H3-Image-PE", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/MiniMaxAI/MiniMax-H3-Image-PE
- SGLang
How to use MiniMaxAI/MiniMax-H3-Image-PE with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "MiniMaxAI/MiniMax-H3-Image-PE" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "MiniMaxAI/MiniMax-H3-Image-PE", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "MiniMaxAI/MiniMax-H3-Image-PE" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "MiniMaxAI/MiniMax-H3-Image-PE", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Docker Model Runner
How to use MiniMaxAI/MiniMax-H3-Image-PE with Docker Model Runner:
docker model run hf.co/MiniMaxAI/MiniMax-H3-Image-PE
Download scripts/expand_prompt.py from MiniMaxAI/MiniMax-H3-Image-PE: direct link, hf CLI and curl.
- Browser
- Download file 5.81 kB
-
https://huggingface.co/MiniMaxAI/MiniMax-H3-Image-PE/resolve/main/scripts/expand_prompt.py
- Command line
-
hf download hf://MiniMaxAI/MiniMax-H3-Image-PE/scripts/expand_prompt.py
-
curl -L -o expand_prompt.py https://huggingface.co/MiniMaxAI/MiniMax-H3-Image-PE/resolve/main/scripts/expand_prompt.py
5.81 kB
| #!/usr/bin/env python3 | |
| """Expand a short text-to-image prompt with MiniMax-H3-Image-PE. | |
| Sends the supplied release request (system prompt, user template, | |
| sampling parameters and JSON schema from ../prompt/t2i/) to an OpenAI-compatible | |
| chat endpoint, checks the answer and prints | |
| {"expanded_caption": ..., "aspect_ratio": ...}. | |
| python3 scripts/expand_prompt.py --url http://127.0.0.1:30000 "a lighthouse on a cliff at sunset" | |
| """ | |
| import argparse | |
| import json | |
| import os | |
| import sys | |
| import urllib.request | |
| from pathlib import Path | |
| # absolute(), not resolve(): in the Hugging Face cache this file is a symlink into blobs/. | |
| PROMPT_DIR = Path(__file__).absolute().parent.parent / "prompt" / "t2i" | |
| def build_request(prompt: str, model: str) -> dict: | |
| if not isinstance(prompt, str) or not prompt.strip(): | |
| raise ValueError("prompt must be a non-empty string") | |
| if not isinstance(model, str) or not model.strip(): | |
| raise ValueError("model must be a non-empty string") | |
| system_prompt = (PROMPT_DIR / "system_prompt.txt").read_text(encoding="utf-8").rstrip("\n") | |
| template = (PROMPT_DIR / "task_prompt.txt").read_text(encoding="utf-8") | |
| body = json.loads((PROMPT_DIR / "request_params.json").read_text(encoding="utf-8")) | |
| body.update( | |
| model=model, | |
| messages=[ | |
| {"role": "system", "content": system_prompt}, | |
| {"role": "user", "content": template.format(prompt)}, | |
| ], | |
| stream=False, | |
| ) | |
| return body | |
| def parse_response(response: dict, allowed_ratios: list) -> dict: | |
| choices = response.get("choices") if isinstance(response, dict) else None | |
| if not isinstance(choices, list) or len(choices) != 1 or not isinstance(choices[0], dict): | |
| raise ValueError("expected exactly one response choice") | |
| choice = choices[0] | |
| if choice.get("finish_reason") != "stop": | |
| raise ValueError(f"generation did not finish: finish_reason={choice.get('finish_reason')!r}") | |
| message = choice.get("message") | |
| if not isinstance(message, dict): | |
| raise ValueError("expected a response message") | |
| thinking = message.get("reasoning_content") | |
| if not isinstance(thinking, str) or not thinking.strip(): | |
| raise ValueError("no thinking section; start the server with --reasoning-parser qwen3") | |
| if not isinstance(message.get("content"), str): | |
| raise ValueError("expected JSON text in message.content") | |
| result = json.loads(message["content"]) | |
| if not isinstance(result, dict) or set(result) != {"expanded_caption", "aspect_ratio"}: | |
| raise ValueError("expected exactly expanded_caption and aspect_ratio") | |
| if not isinstance(result["aspect_ratio"], str) or result["aspect_ratio"] not in allowed_ratios: | |
| raise ValueError(f"unsupported aspect ratio: {result['aspect_ratio']!r}") | |
| if not isinstance(result["expanded_caption"], str) or not result["expanded_caption"].strip(): | |
| raise ValueError("expanded_caption must be a non-empty string") | |
| return {"expanded_caption": result["expanded_caption"].strip(), "aspect_ratio": result["aspect_ratio"]} | |
| def select_model(response: dict) -> str: | |
| models = response.get("data") if isinstance(response, dict) else None | |
| if not isinstance(models, list) or len(models) != 1: | |
| raise ValueError("server must expose exactly one model; specify --model explicitly") | |
| model = models[0].get("id") if isinstance(models[0], dict) else None | |
| if not isinstance(model, str) or not model.strip(): | |
| raise ValueError("server returned an invalid model ID; specify --model explicitly") | |
| return model | |
| def main() -> int: | |
| ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) | |
| ap.add_argument("prompt", help="short prompt, any language") | |
| ap.add_argument("--url", default="http://127.0.0.1:30000", help="server base URL") | |
| ap.add_argument("--model", default=None, help="served model name (default: the server's only model)") | |
| ap.add_argument("--timeout", type=float, default=1200) | |
| ap.add_argument("--save-response", type=Path, default=None, help="also write the raw chat response here") | |
| ap.add_argument("--dry-run", action="store_true", help="print the request without network access; requires --model") | |
| ap.add_argument("--api-key-env", default="OPENAI_API_KEY", help="optional environment variable holding a bearer token") | |
| args = ap.parse_args() | |
| if args.dry_run: | |
| if not args.model: | |
| ap.error("--dry-run requires --model") | |
| print(json.dumps(build_request(args.prompt, args.model), ensure_ascii=False, indent=2)) | |
| return 0 | |
| base = args.url.rstrip("/") | |
| if not base.endswith("/v1"): | |
| base += "/v1" | |
| headers = {"Content-Type": "application/json"} | |
| api_key = os.environ.get(args.api_key_env) | |
| if api_key: | |
| headers["Authorization"] = f"Bearer {api_key}" | |
| model = args.model | |
| if model is None: | |
| request = urllib.request.Request(f"{base}/models", headers=headers) | |
| with urllib.request.urlopen(request, timeout=args.timeout) as r: | |
| model = select_model(json.load(r)) | |
| body = build_request(args.prompt, model) | |
| req = urllib.request.Request(f"{base}/chat/completions", data=json.dumps(body).encode(), | |
| headers=headers) | |
| with urllib.request.urlopen(req, timeout=args.timeout) as r: | |
| response = json.load(r) | |
| if args.save_response: | |
| args.save_response.write_text(json.dumps(response, ensure_ascii=False, indent=2) + "\n", encoding="utf-8") | |
| ratios = body["response_format"]["json_schema"]["schema"]["properties"]["aspect_ratio"]["enum"] | |
| print(json.dumps(parse_response(response, ratios), ensure_ascii=False, indent=2)) | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(main()) | |