Image-Text-to-Text
Transformers
Safetensors
English
molmo2
vision-language
multimodal
nvfp4
fp4
quantized
vllm
molmo
conversational
custom_code
8-bit precision
compressed-tensors
Instructions to use tollea1234/Molmo2-4B-NVFP4 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use tollea1234/Molmo2-4B-NVFP4 with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="tollea1234/Molmo2-4B-NVFP4", trust_remote_code=True) 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)# Load model directly from transformers import AutoModelForImageTextToText model = AutoModelForImageTextToText.from_pretrained("tollea1234/Molmo2-4B-NVFP4", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use tollea1234/Molmo2-4B-NVFP4 with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "tollea1234/Molmo2-4B-NVFP4" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "tollea1234/Molmo2-4B-NVFP4", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker
docker model run hf.co/tollea1234/Molmo2-4B-NVFP4
- SGLang
How to use tollea1234/Molmo2-4B-NVFP4 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 "tollea1234/Molmo2-4B-NVFP4" \ --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": "tollea1234/Molmo2-4B-NVFP4", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'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 "tollea1234/Molmo2-4B-NVFP4" \ --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": "tollea1234/Molmo2-4B-NVFP4", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }' - Docker Model Runner
How to use tollea1234/Molmo2-4B-NVFP4 with Docker Model Runner:
docker model run hf.co/tollea1234/Molmo2-4B-NVFP4
| import argparse | |
| import torch | |
| from datasets import load_dataset | |
| from transformers import AutoProcessor, AutoModelForImageTextToText | |
| from llmcompressor import oneshot | |
| from llmcompressor.modifiers.quantization import QuantizationModifier | |
| from llmcompressor.utils import dispatch_for_generation | |
| # NOTE: Requires a minimum of transformers 4.57.0 | |
| def parse_args(): | |
| parser = argparse.ArgumentParser(description="Quantize Molmo2 model") | |
| parser.add_argument( | |
| "--model-id", | |
| type=str, | |
| default="allenai/Molmo2-4B", | |
| help="HuggingFace model ID (default: allenai/Molmo2-8B)", | |
| ) | |
| parser.add_argument( | |
| "--quant-type", | |
| type=str, | |
| choices=["nvfp4", "fp8"], | |
| default="nvfp4", | |
| help="Quantization type: nvfp4 or fp8 (default: nvfp4)", | |
| ) | |
| parser.add_argument( | |
| "--num-calibration-samples", | |
| type=int, | |
| default=256, | |
| help="Number of calibration samples (default: 256)", | |
| ) | |
| parser.add_argument( | |
| "--max-seq-length", | |
| type=int, | |
| default=8192, | |
| help="Maximum sequence length (default: 8192)", | |
| ) | |
| parser.add_argument( | |
| "--output-dir", | |
| type=str, | |
| default=None, | |
| help="Output directory (default: auto-generated based on model and quant type)", | |
| ) | |
| return parser.parse_args() | |
| def get_quantization_recipe(quant_type: str) -> QuantizationModifier: | |
| """Get quantization recipe based on quantization type.""" | |
| ignore_patterns = [ | |
| "re:.*lm_head", | |
| "re:.*vision_backbone.*", # Molmo2 vision encoder | |
| "re:.*mlp.gate$", | |
| ] | |
| if quant_type == "nvfp4": | |
| # NVFP4: 4-bit weights and activations with group-wise quantization | |
| return QuantizationModifier( | |
| targets="Linear", | |
| scheme="NVFP4", | |
| ignore=ignore_patterns, | |
| ) | |
| elif quant_type == "fp8": | |
| # FP8: 8-bit floating point quantization (W8A8) | |
| return QuantizationModifier( | |
| targets="Linear", | |
| scheme="FP8", | |
| ignore=ignore_patterns, | |
| ) | |
| else: | |
| raise ValueError(f"Unsupported quantization type: {quant_type}") | |
| args = parse_args() | |
| MODEL_ID = args.model_id | |
| QUANT_TYPE = args.quant_type.upper() | |
| NUM_CALIBRATION_SAMPLES = args.num_calibration_samples | |
| MAX_SEQUENCE_LENGTH = args.max_seq_length | |
| print(f"Model: {MODEL_ID}") | |
| print(f"Quantization: {QUANT_TYPE}") | |
| print(f"Calibration samples: {NUM_CALIBRATION_SAMPLES}") | |
| print(f"Max sequence length: {MAX_SEQUENCE_LENGTH}") | |
| # Load model. | |
| model = AutoModelForImageTextToText.from_pretrained(MODEL_ID, torch_dtype="auto", trust_remote_code=True) | |
| processor = AutoProcessor.from_pretrained(MODEL_ID, trust_remote_code=True) | |
| DATASET_ID = "neuralmagic/calibration" | |
| ds = load_dataset(DATASET_ID, name="LLM", split=f"train[:{NUM_CALIBRATION_SAMPLES}]") | |
| def preprocess_function(example): | |
| messgages = [] | |
| for message in example["messages"]: | |
| messgages.append( | |
| { | |
| "role": message["role"], | |
| "content": [{"type": "text", "text": message["content"]}], | |
| } | |
| ) | |
| return processor.apply_chat_template( | |
| messgages, | |
| return_tensors="pt", | |
| padding=False, | |
| truncation=True, | |
| max_length=MAX_SEQUENCE_LENGTH, | |
| tokenize=True, | |
| add_special_tokens=False, | |
| return_dict=True, | |
| add_generation_prompt=False, | |
| ) | |
| ds = ds.map(preprocess_function, batched=False, remove_columns=ds.column_names) | |
| def data_collator(batch): | |
| assert len(batch) == 1 | |
| return { | |
| key: ( | |
| torch.tensor(value) | |
| if key != "pixel_values" | |
| else torch.tensor(value, dtype=torch.bfloat16).squeeze(0) | |
| ) | |
| for key, value in batch[0].items() | |
| } | |
| # Configure the quantization algorithm and scheme. | |
| recipe = get_quantization_recipe(args.quant_type) | |
| # Apply quantization. | |
| oneshot( | |
| model=model, | |
| processor=processor, | |
| recipe=recipe, | |
| max_seq_length=MAX_SEQUENCE_LENGTH, | |
| num_calibration_samples=NUM_CALIBRATION_SAMPLES, | |
| dataset=ds, | |
| data_collator=data_collator, | |
| ) | |
| print("========== SAMPLE GENERATION ==============") | |
| dispatch_for_generation(model) | |
| input_ids = processor(text="Hello my name is", return_tensors="pt").input_ids.to("cuda") | |
| output = model.generate(input_ids, max_new_tokens=20) | |
| print(processor.decode(output[0])) | |
| print("==========================================") | |
| # Save to disk in compressed-tensors format. | |
| if args.output_dir: | |
| SAVE_DIR = args.output_dir | |
| else: | |
| SAVE_DIR = MODEL_ID.rstrip("/").split("/")[-1] + f"-{QUANT_TYPE}" | |
| print(f"Saving to: {SAVE_DIR}") | |
| model.save_pretrained(SAVE_DIR) | |
| # Save processor (handle compatibility issues with some processor types) | |
| try: | |
| processor.save_pretrained(SAVE_DIR) | |
| except AttributeError: | |
| # Fallback: save tokenizer and image_processor separately | |
| if hasattr(processor, "tokenizer"): | |
| processor.tokenizer.save_pretrained(SAVE_DIR) | |
| if hasattr(processor, "image_processor"): | |
| processor.image_processor.save_pretrained(SAVE_DIR) | |
| print("Done!") |