Skip to content

vllm_mlx.benchmark

Performance Benchmark for vllm-mlx.

View the complete module source at #L1-L1684.

API details

Each callable below includes its exact signature, type annotations, inputs, defaults, return contract, documented exceptions, implementation source, and parsed docstring sections when the source provides them.

vllm_mlx.benchmark

Performance Benchmark for vllm-mlx.

Measures key performance metrics for LLM and MLLM (Multimodal Language Model) inference: - Time to First Token (TTFT) - Time Per Output Token (TPOT) - Tokens Per Second (TPS) - both input processing and output generation - End-to-End Latency - Throughput - Memory Usage (process and MLX cache) - MLLM: Image resolution performance - MLLM: Video frame count performance

Usage

LLM benchmark

python -m vllm_mlx.benchmark --model mlx-community/Llama-3.2-1B-Instruct-4bit python -m vllm_mlx.benchmark --model mlx-community/Llama-3.2-3B-Instruct-4bit --prompts 10 --max-tokens 256

MLLM image benchmark (auto-detected or use --mllm flag)

python -m vllm_mlx.benchmark --model mlx-community/Qwen3-VL-4B-Instruct-3bit python -m vllm_mlx.benchmark --model mlx-community/Qwen3-VL-4B-Instruct-3bit --mllm --quick

MLLM video benchmark

python -m vllm_mlx.benchmark --model mlx-community/Qwen3-VL-4B-Instruct-3bit --video python -m vllm_mlx.benchmark --model mlx-community/Qwen3-VL-4B-Instruct-3bit --video --video-url https://example.com/video.mp4

vllm_mlx.benchmark.VIDEO_SAMPLE_URLS module-attribute

VIDEO_SAMPLE_URLS = {'bunny_10s': 'https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/360/Big_Buck_Bunny_360_10s_1MB.mp4', 'bunny_240p': 'https://docs.evostream.com/sample_content/assets/bunny.mp4', 'sintel_720p': 'https://docs.evostream.com/sample_content/assets/sintel1m720p.mp4'}

vllm_mlx.benchmark.DEFAULT_VIDEO_URL module-attribute

DEFAULT_VIDEO_URL = VIDEO_SAMPLE_URLS['bunny_10s']

vllm_mlx.benchmark.VLM_TEST_VIDEO_URLS module-attribute

VLM_TEST_VIDEO_URLS = [VIDEO_SAMPLE_URLS['bunny_10s'], VIDEO_SAMPLE_URLS['bunny_240p']]

vllm_mlx.benchmark.MLLM_PATTERNS module-attribute

MLLM_PATTERNS = ['-VL-', '-VL/', 'VL-', 'llava', 'LLaVA', 'idefics', 'Idefics', 'paligemma', 'PaliGemma', 'pixtral', 'Pixtral', 'molmo', 'Molmo', 'phi3-vision', 'phi-3-vision', 'cogvlm', 'CogVLM', 'internvl', 'InternVL', 'deepseek-vl', 'DeepSeek-VL']

vllm_mlx.benchmark.MLLM_TEST_IMAGE_URL module-attribute

MLLM_TEST_IMAGE_URL = 'https://upload.wikimedia.org/wikipedia/commons/thumb/2/26/YellowLabradorLooking_new.jpg/1200px-YellowLabradorLooking_new.jpg'

vllm_mlx.benchmark.MLLM_TEST_IMAGE_URLS module-attribute

MLLM_TEST_IMAGE_URLS = [MLLM_TEST_IMAGE_URL, 'https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg', 'https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/PNG_transparency_demonstration_1.png/640px-PNG_transparency_demonstration_1.png']

vllm_mlx.benchmark.ResourceMetrics dataclass

ResourceMetrics(process_memory_gb: float = 0.0, mlx_cache_gb: float = 0.0, mlx_peak_memory_gb: float = 0.0, system_memory_used_gb: float = 0.0, system_memory_total_gb: float = 0.0)

Resource usage metrics during benchmark.

vllm_mlx.benchmark.ResourceMetrics.process_memory_gb class-attribute instance-attribute

process_memory_gb: float = 0.0

vllm_mlx.benchmark.ResourceMetrics.mlx_cache_gb class-attribute instance-attribute

mlx_cache_gb: float = 0.0

vllm_mlx.benchmark.ResourceMetrics.mlx_peak_memory_gb class-attribute instance-attribute

mlx_peak_memory_gb: float = 0.0

vllm_mlx.benchmark.ResourceMetrics.system_memory_used_gb class-attribute instance-attribute

system_memory_used_gb: float = 0.0

vllm_mlx.benchmark.ResourceMetrics.system_memory_total_gb class-attribute instance-attribute

system_memory_total_gb: float = 0.0

vllm_mlx.benchmark.ResourceMonitor

ResourceMonitor()

Monitor system resources during benchmark runs.

Source code in vllm_mlx/benchmark.py
def __init__(self):
    self.samples: list[ResourceMetrics] = []
    self._start_time: float = 0
    self._start_memory: float = 0

vllm_mlx.benchmark.ResourceMonitor.samples instance-attribute

samples: list[ResourceMetrics] = []

vllm_mlx.benchmark.ResourceMonitor._start_time instance-attribute

_start_time: float = 0

vllm_mlx.benchmark.ResourceMonitor._start_memory instance-attribute

_start_memory: float = 0

vllm_mlx.benchmark.ResourceMonitor.start

start()

Start monitoring.

Source code in vllm_mlx/benchmark.py
def start(self):
    """Start monitoring."""
    self._start_time = time.perf_counter()
    self._start_memory = get_process_memory()

    # Reset MLX peak memory
    reset_mlx_peak_memory()

vllm_mlx.benchmark.ResourceMonitor.sample

sample() -> ResourceMetrics

Take a resource sample.

Source code in vllm_mlx/benchmark.py
def sample(self) -> ResourceMetrics:
    """Take a resource sample."""
    mlx_info = get_mlx_memory_info()
    sys_used, sys_total = get_system_memory()

    metrics = ResourceMetrics(
        process_memory_gb=get_process_memory(),
        mlx_cache_gb=mlx_info.get("cache_memory_gb", 0.0),
        mlx_peak_memory_gb=mlx_info.get("peak_memory_gb", 0.0),
        system_memory_used_gb=sys_used,
        system_memory_total_gb=sys_total,
    )

    self.samples.append(metrics)
    return metrics

vllm_mlx.benchmark.ResourceMonitor.get_summary

get_summary() -> ResourceMetrics

Get summary of all samples.

Source code in vllm_mlx/benchmark.py
def get_summary(self) -> ResourceMetrics:
    """Get summary of all samples."""
    if not self.samples:
        return ResourceMetrics()

    # Get peak values
    peak_process = max(s.process_memory_gb for s in self.samples)
    peak_mlx = max(s.mlx_peak_memory_gb for s in self.samples)
    peak_mlx_cache = max(s.mlx_cache_gb for s in self.samples)

    # Get latest system memory
    latest = self.samples[-1]

    return ResourceMetrics(
        process_memory_gb=peak_process,
        mlx_cache_gb=peak_mlx_cache,
        mlx_peak_memory_gb=peak_mlx,
        system_memory_used_gb=latest.system_memory_used_gb,
        system_memory_total_gb=latest.system_memory_total_gb,
    )

vllm_mlx.benchmark.BenchmarkResult dataclass

BenchmarkResult(prompt: str, prompt_tokens: int, generated_tokens: int, ttft: float, total_time: float, tpot: float = 0.0, generation_tps: float = 0.0, processing_tps: float = 0.0)

Results from a single benchmark run.

vllm_mlx.benchmark.BenchmarkResult.prompt instance-attribute

prompt: str

vllm_mlx.benchmark.BenchmarkResult.prompt_tokens instance-attribute

prompt_tokens: int

vllm_mlx.benchmark.BenchmarkResult.generated_tokens instance-attribute

generated_tokens: int

vllm_mlx.benchmark.BenchmarkResult.ttft instance-attribute

ttft: float

vllm_mlx.benchmark.BenchmarkResult.total_time instance-attribute

total_time: float

vllm_mlx.benchmark.BenchmarkResult.tpot class-attribute instance-attribute

tpot: float = 0.0

vllm_mlx.benchmark.BenchmarkResult.generation_tps class-attribute instance-attribute

generation_tps: float = 0.0

vllm_mlx.benchmark.BenchmarkResult.processing_tps class-attribute instance-attribute

processing_tps: float = 0.0

vllm_mlx.benchmark.BenchmarkResult.__post_init__

__post_init__()
Source code in vllm_mlx/benchmark.py
def __post_init__(self):
    if self.generated_tokens > 1:
        # TPOT excludes the first token (which is measured by TTFT)
        generation_time = self.total_time - self.ttft
        self.tpot = (
            generation_time / (self.generated_tokens - 1)
            if self.generated_tokens > 1
            else 0
        )
        self.generation_tps = (
            (self.generated_tokens - 1) / generation_time
            if generation_time > 0
            else 0
        )

    # Processing TPS: how fast the prompt was processed (tokens / TTFT)
    if self.ttft > 0:
        self.processing_tps = self.prompt_tokens / self.ttft

vllm_mlx.benchmark.BenchmarkSummary dataclass

BenchmarkSummary(model_name: str, num_runs: int, total_prompt_tokens: int, total_generated_tokens: int, total_time: float, ttft_mean: float, ttft_min: float, ttft_max: float, ttft_p50: float, ttft_p95: float, tpot_mean: float, tpot_min: float, tpot_max: float, generation_tps_mean: float, generation_tps_max: float, processing_tps_mean: float, latency_mean: float, latency_min: float, latency_max: float, latency_p50: float, latency_p95: float, total_throughput_tps: float, requests_per_second: float, hardware_chip: str = '', hardware_memory_gb: float = 0.0, hardware_bandwidth_gbs: float = 0.0, resources: ResourceMetrics = ResourceMetrics())

Summary statistics across all benchmark runs.

vllm_mlx.benchmark.BenchmarkSummary.model_name instance-attribute

model_name: str

vllm_mlx.benchmark.BenchmarkSummary.num_runs instance-attribute

num_runs: int

vllm_mlx.benchmark.BenchmarkSummary.total_prompt_tokens instance-attribute

total_prompt_tokens: int

vllm_mlx.benchmark.BenchmarkSummary.total_generated_tokens instance-attribute

total_generated_tokens: int

vllm_mlx.benchmark.BenchmarkSummary.total_time instance-attribute

total_time: float

vllm_mlx.benchmark.BenchmarkSummary.ttft_mean instance-attribute

ttft_mean: float

vllm_mlx.benchmark.BenchmarkSummary.ttft_min instance-attribute

ttft_min: float

vllm_mlx.benchmark.BenchmarkSummary.ttft_max instance-attribute

ttft_max: float

vllm_mlx.benchmark.BenchmarkSummary.ttft_p50 instance-attribute

ttft_p50: float

vllm_mlx.benchmark.BenchmarkSummary.ttft_p95 instance-attribute

ttft_p95: float

vllm_mlx.benchmark.BenchmarkSummary.tpot_mean instance-attribute

tpot_mean: float

vllm_mlx.benchmark.BenchmarkSummary.tpot_min instance-attribute

tpot_min: float

vllm_mlx.benchmark.BenchmarkSummary.tpot_max instance-attribute

tpot_max: float

vllm_mlx.benchmark.BenchmarkSummary.generation_tps_mean instance-attribute

generation_tps_mean: float

vllm_mlx.benchmark.BenchmarkSummary.generation_tps_max instance-attribute

generation_tps_max: float

vllm_mlx.benchmark.BenchmarkSummary.processing_tps_mean instance-attribute

processing_tps_mean: float

vllm_mlx.benchmark.BenchmarkSummary.latency_mean instance-attribute

latency_mean: float

vllm_mlx.benchmark.BenchmarkSummary.latency_min instance-attribute

latency_min: float

vllm_mlx.benchmark.BenchmarkSummary.latency_max instance-attribute

latency_max: float

vllm_mlx.benchmark.BenchmarkSummary.latency_p50 instance-attribute

latency_p50: float

vllm_mlx.benchmark.BenchmarkSummary.latency_p95 instance-attribute

latency_p95: float

vllm_mlx.benchmark.BenchmarkSummary.total_throughput_tps instance-attribute

total_throughput_tps: float

vllm_mlx.benchmark.BenchmarkSummary.requests_per_second instance-attribute

requests_per_second: float

vllm_mlx.benchmark.BenchmarkSummary.hardware_chip class-attribute instance-attribute

hardware_chip: str = ''

vllm_mlx.benchmark.BenchmarkSummary.hardware_memory_gb class-attribute instance-attribute

hardware_memory_gb: float = 0.0

vllm_mlx.benchmark.BenchmarkSummary.hardware_bandwidth_gbs class-attribute instance-attribute

hardware_bandwidth_gbs: float = 0.0

vllm_mlx.benchmark.BenchmarkSummary.resources class-attribute instance-attribute

resources: ResourceMetrics = field(default_factory=ResourceMetrics)

vllm_mlx.benchmark.MLLMBenchmarkResult dataclass

MLLMBenchmarkResult(resolution: str, width: int, height: int, pixels: int, time_seconds: float, tokens_generated: int, tokens_per_second: float, response_preview: str, memory_gb: float = 0.0, mlx_memory_gb: float = 0.0)

Result from a single MLLM benchmark run.

vllm_mlx.benchmark.MLLMBenchmarkResult.resolution instance-attribute

resolution: str

vllm_mlx.benchmark.MLLMBenchmarkResult.width instance-attribute

width: int

vllm_mlx.benchmark.MLLMBenchmarkResult.height instance-attribute

height: int

vllm_mlx.benchmark.MLLMBenchmarkResult.pixels instance-attribute

pixels: int

vllm_mlx.benchmark.MLLMBenchmarkResult.time_seconds instance-attribute

time_seconds: float

vllm_mlx.benchmark.MLLMBenchmarkResult.tokens_generated instance-attribute

tokens_generated: int

vllm_mlx.benchmark.MLLMBenchmarkResult.tokens_per_second instance-attribute

tokens_per_second: float

vllm_mlx.benchmark.MLLMBenchmarkResult.response_preview instance-attribute

response_preview: str

vllm_mlx.benchmark.MLLMBenchmarkResult.memory_gb class-attribute instance-attribute

memory_gb: float = 0.0

vllm_mlx.benchmark.MLLMBenchmarkResult.mlx_memory_gb class-attribute instance-attribute

mlx_memory_gb: float = 0.0

vllm_mlx.benchmark.VideoBenchmarkResult dataclass

VideoBenchmarkResult(config_name: str, fps: float, max_frames: int, frames_extracted: int, video_duration: float, time_seconds: float, prompt_tokens: int, completion_tokens: int, tokens_per_second: float, response_preview: str, memory_gb: float = 0.0, mlx_memory_gb: float = 0.0)

Result from a single video benchmark run.

vllm_mlx.benchmark.VideoBenchmarkResult.config_name instance-attribute

config_name: str

vllm_mlx.benchmark.VideoBenchmarkResult.fps instance-attribute

fps: float

vllm_mlx.benchmark.VideoBenchmarkResult.max_frames instance-attribute

max_frames: int

vllm_mlx.benchmark.VideoBenchmarkResult.frames_extracted instance-attribute

frames_extracted: int

vllm_mlx.benchmark.VideoBenchmarkResult.video_duration instance-attribute

video_duration: float

vllm_mlx.benchmark.VideoBenchmarkResult.time_seconds instance-attribute

time_seconds: float

vllm_mlx.benchmark.VideoBenchmarkResult.prompt_tokens instance-attribute

prompt_tokens: int

vllm_mlx.benchmark.VideoBenchmarkResult.completion_tokens instance-attribute

completion_tokens: int

vllm_mlx.benchmark.VideoBenchmarkResult.tokens_per_second instance-attribute

tokens_per_second: float

vllm_mlx.benchmark.VideoBenchmarkResult.response_preview instance-attribute

response_preview: str

vllm_mlx.benchmark.VideoBenchmarkResult.memory_gb class-attribute instance-attribute

memory_gb: float = 0.0

vllm_mlx.benchmark.VideoBenchmarkResult.mlx_memory_gb class-attribute instance-attribute

mlx_memory_gb: float = 0.0

vllm_mlx.benchmark.reset_mlx_peak_memory

reset_mlx_peak_memory()

Reset MLX peak memory counter.

Source code in vllm_mlx/benchmark.py
def reset_mlx_peak_memory():
    """Reset MLX peak memory counter."""
    if not HAS_MLX:
        return

    try:
        # Use new API (mx.*) if available, fallback to deprecated (mx.metal.*)
        if hasattr(mx, "reset_peak_memory"):
            mx.reset_peak_memory()
        else:
            mx.metal.reset_peak_memory()
    except Exception:
        pass

vllm_mlx.benchmark.get_mlx_memory_info

get_mlx_memory_info(reset_peak: bool = True) -> dict

Get MLX memory usage information.

Parameters:

  • reset_peak (bool, default: True ) –

    If True, reset peak memory counter after reading.

Source code in vllm_mlx/benchmark.py
def get_mlx_memory_info(reset_peak: bool = True) -> dict:
    """Get MLX memory usage information.

    Args:
        reset_peak: If True, reset peak memory counter after reading.
    """
    if not HAS_MLX:
        return {}

    try:
        # Use new API (mx.*) if available, fallback to deprecated (mx.metal.*)
        if hasattr(mx, "get_cache_memory"):
            cache_memory = mx.get_cache_memory()
            peak_memory = mx.get_peak_memory()
            active_memory = (
                mx.get_active_memory() if hasattr(mx, "get_active_memory") else 0
            )
        else:
            # Fallback for older MLX versions
            cache_memory = mx.metal.get_cache_memory()
            peak_memory = mx.metal.get_peak_memory()
            active_memory = (
                mx.metal.get_active_memory()
                if hasattr(mx.metal, "get_active_memory")
                else 0
            )

        info = {
            "cache_memory_gb": cache_memory / (1024**3),
            "peak_memory_gb": peak_memory / (1024**3),
            "active_memory_gb": active_memory / (1024**3),
        }
        # Reset peak for next measurement if requested
        if reset_peak:
            reset_mlx_peak_memory()
        return info
    except Exception:
        return {}

vllm_mlx.benchmark.get_process_memory

get_process_memory() -> float

Get current process memory usage in GB.

Source code in vllm_mlx/benchmark.py
def get_process_memory() -> float:
    """Get current process memory usage in GB."""
    if not HAS_PSUTIL:
        return 0.0

    try:
        process = psutil.Process()
        return process.memory_info().rss / (1024**3)
    except Exception:
        return 0.0

vllm_mlx.benchmark.get_system_memory

get_system_memory() -> tuple[float, float]

Get system memory (used, total) in GB.

Source code in vllm_mlx/benchmark.py
def get_system_memory() -> tuple[float, float]:
    """Get system memory (used, total) in GB."""
    if not HAS_PSUTIL:
        return 0.0, 0.0

    try:
        mem = psutil.virtual_memory()
        return mem.used / (1024**3), mem.total / (1024**3)
    except Exception:
        return 0.0, 0.0

vllm_mlx.benchmark.calculate_percentile

calculate_percentile(data: list, percentile: float) -> float

Calculate percentile from a list.

Source code in vllm_mlx/benchmark.py
def calculate_percentile(data: list, percentile: float) -> float:
    """Calculate percentile from a list."""
    if not data:
        return 0.0
    sorted_data = sorted(data)
    index = int(len(sorted_data) * percentile / 100)
    index = min(index, len(sorted_data) - 1)
    return sorted_data[index]

vllm_mlx.benchmark.benchmark_single_prompt

benchmark_single_prompt(model, tokenizer, prompt: str, max_tokens: int = 256, temperature: float = 0.7) -> Optional[BenchmarkResult]

Benchmark a single prompt with detailed timing.

Parameters:

  • model

    The loaded MLX model

  • tokenizer

    The tokenizer

  • prompt (str) –

    The prompt to benchmark

  • max_tokens (int, default: 256 ) –

    Maximum tokens to generate

  • temperature (float, default: 0.7 ) –

    Sampling temperature

Returns:

Source code in vllm_mlx/benchmark.py
def benchmark_single_prompt(
    model,
    tokenizer,
    prompt: str,
    max_tokens: int = 256,
    temperature: float = 0.7,
) -> Optional[BenchmarkResult]:
    """
    Benchmark a single prompt with detailed timing.

    Args:
        model: The loaded MLX model
        tokenizer: The tokenizer
        prompt: The prompt to benchmark
        max_tokens: Maximum tokens to generate
        temperature: Sampling temperature

    Returns:
        BenchmarkResult with timing metrics
    """
    from mlx_lm import stream_generate
    from mlx_lm.sample_utils import make_sampler

    try:
        # Tokenize the prompt to count tokens
        prompt_tokens = tokenizer.encode(prompt)
        prompt_token_count = len(prompt_tokens)

        # Create sampler
        sampler = make_sampler(temp=temperature)

        # Start timing
        start_time = time.perf_counter()
        ttft = None
        token_count = 0

        # Generate tokens using stream_generate
        for response in stream_generate(
            model,
            tokenizer,
            prompt,
            max_tokens=max_tokens,
            sampler=sampler,
        ):
            if ttft is None:
                ttft = time.perf_counter() - start_time
            token_count += 1

        total_time = time.perf_counter() - start_time

        if ttft is None:
            ttft = total_time

        return BenchmarkResult(
            prompt=prompt[:50] + "..." if len(prompt) > 50 else prompt,
            prompt_tokens=prompt_token_count,
            generated_tokens=token_count,
            ttft=ttft,
            total_time=total_time,
        )

    except Exception as e:
        print(f"Error during benchmark: {e}")
        import traceback

        traceback.print_exc()
        return None

vllm_mlx.benchmark.run_benchmark

run_benchmark(model_name: str, num_prompts: int = 5, max_tokens: int = 256, temperature: float = 0.7, warmup_runs: int = 1) -> Optional[BenchmarkSummary]

Run the full benchmark suite.

Parameters:

  • model_name (str) –

    HuggingFace model name or local path

  • num_prompts (int, default: 5 ) –

    Number of prompts to test

  • max_tokens (int, default: 256 ) –

    Maximum tokens per generation

  • temperature (float, default: 0.7 ) –

    Sampling temperature

  • warmup_runs (int, default: 1 ) –

    Number of warmup runs before measuring

Returns:

Source code in vllm_mlx/benchmark.py
def run_benchmark(
    model_name: str,
    num_prompts: int = 5,
    max_tokens: int = 256,
    temperature: float = 0.7,
    warmup_runs: int = 1,
) -> Optional[BenchmarkSummary]:
    """
    Run the full benchmark suite.

    Args:
        model_name: HuggingFace model name or local path
        num_prompts: Number of prompts to test
        max_tokens: Maximum tokens per generation
        temperature: Sampling temperature
        warmup_runs: Number of warmup runs before measuring

    Returns:
        BenchmarkSummary with aggregate statistics
    """
    from vllm_mlx.utils.tokenizer import load_model_with_fallback
    from vllm_mlx.optimizations import detect_hardware

    # Detect hardware
    hw = detect_hardware()

    # Test prompts of varying lengths: 3 short, 3 medium, 4 long
    prompts = [
        # Short prompts (~5-15 tokens) - 3 prompts
        "Hello, how are you?",
        "What is 2+2?",
        "Say hello in Spanish.",
        # Medium prompts (~30-60 tokens) - 3 prompts
        "What is the capital of France and why is it historically significant? Include some interesting facts about the city.",
        "Write a Python function to calculate fibonacci numbers using memoization. Explain how it works.",
        "Explain the difference between a list and a tuple in Python. When should you use each one?",
        # Long prompts (100+ tokens) - 4 prompts
        """Explain quantum computing in comprehensive detail. You should cover all of the following topics thoroughly:
        1. What are qubits and how do they fundamentally differ from classical bits in traditional computing?
        2. What is quantum superposition and how does it enable parallel computation?
        3. What is quantum entanglement and why is it crucial for quantum algorithms?
        4. What are the most promising potential applications of quantum computing in cryptography, drug discovery, and optimization?
        5. What are the current hardware limitations, error correction challenges, and decoherence problems?
        6. Compare the approaches of IBM, Google, and other major players in quantum computing research.""",
        """Write a comprehensive and detailed guide to building a production-ready REST API with Python Flask. Include all of the following sections with code examples:
        1. Setting up the project structure with blueprints, configuration management, and environment variables
        2. Creating routes and endpoints following RESTful conventions with proper HTTP methods
        3. Handling JSON requests and responses with validation using marshmallow or pydantic
        4. Adding authentication and authorization with JWT tokens and role-based access control
        5. Implementing error handling best practices with custom exception handlers
        6. Writing comprehensive tests with pytest including unit tests and integration tests
        7. Setting up logging, monitoring, and API documentation with Swagger/OpenAPI""",
        """Describe the complete process of photosynthesis in plants with scientific detail. Your explanation should cover:
        1. The light-dependent reactions that occur in the thylakoid membrane, including photosystems I and II
        2. The electron transport chain and chemiosmosis for ATP synthesis
        3. The Calvin cycle (light-independent reactions) and the process of carbon fixation by RuBisCO
        4. The role of chlorophyll a, chlorophyll b, and accessory pigments like carotenoids
        5. How environmental factors like light intensity, CO2 concentration, and temperature affect photosynthesis rate
        6. The importance of photosynthesis for life on Earth and its role in the carbon cycle
        7. C3, C4, and CAM photosynthesis adaptations in different plant species""",
        """You are a senior software architect with 15 years of experience. Design a complete microservices architecture for a large-scale e-commerce platform that handles millions of users. Your design should include:
        1. Service breakdown with detailed responsibilities: User service (authentication, profiles, preferences), Product catalog service (search, filtering, recommendations), Inventory service (stock management, warehouses), Order service (cart, checkout, order history), Payment service (multiple providers, refunds), Notification service (email, SMS, push)
        2. Database choices for each service with justification (PostgreSQL vs MongoDB vs Redis)
        3. Inter-service communication patterns: synchronous REST/gRPC vs asynchronous message queues
        4. API gateway design with rate limiting, authentication, and request routing
        5. Caching strategy with Redis for sessions, product data, and search results
        6. Message queue architecture with RabbitMQ or Kafka for event-driven communication
        7. Kubernetes deployment with horizontal pod autoscaling, health checks, and rolling updates
        8. CI/CD pipeline with GitHub Actions, testing stages, and blue-green deployments""",
    ]

    # Use only the requested number of prompts
    test_prompts = (prompts * ((num_prompts // len(prompts)) + 1))[:num_prompts]

    print(f"\n{'='*60}")
    print("vllm-mlx Performance Benchmark")
    print(f"{'='*60}")

    # Hardware info table
    hw_table = [
        ["Model", model_name],
        ["Hardware", f"{hw.chip_name} ({hw.total_memory_gb:.0f} GB)"],
        ["Memory Bandwidth", f"{hw.memory_bandwidth_gbs} GB/s"],
        ["GPU Cores", hw.gpu_cores],
        ["Prompts", num_prompts],
        ["Max Tokens", max_tokens],
        ["Temperature", temperature],
    ]
    print(tabulate(hw_table, tablefmt="plain"))
    print(f"{'='*60}\n")

    # Initialize resource monitor
    monitor = ResourceMonitor()
    monitor.start()

    # Load model
    print(f"Loading model: {model_name}...")
    load_start = time.perf_counter()
    model, tokenizer = load_model_with_fallback(model_name)
    load_time = time.perf_counter() - load_start
    print(f"Model loaded in {load_time:.2f}s\n")

    # Show prompt length distribution
    prompt_lengths = [len(tokenizer.encode(p)) for p in test_prompts]
    short = sum(1 for length in prompt_lengths if length < 20)
    medium = sum(1 for length in prompt_lengths if 20 <= length < 100)
    long_p = sum(1 for length in prompt_lengths if length >= 100)
    print("Prompt Distribution:")
    dist_data = [
        ["Short (<20 tokens)", short],
        ["Medium (20-100)", medium],
        ["Long (100+)", long_p],
        ["Total input tokens", sum(prompt_lengths)],
    ]
    print(tabulate(dist_data, tablefmt="plain"))
    print()

    # Warmup runs
    if warmup_runs > 0:
        print(f"Running {warmup_runs} warmup run(s)...")
        for i in range(warmup_runs):
            benchmark_single_prompt(
                model, tokenizer, "Hello, how are you?", max_tokens=20
            )

        # Show model memory after warmup (MLX uses lazy evaluation)
        mlx_info = get_mlx_memory_info(reset_peak=True)
        if mlx_info and mlx_info.get("peak_memory_gb", 0) > 0:
            print(f"Model memory: {mlx_info['peak_memory_gb']:.2f} GB (MLX peak)")
        print("Warmup complete.\n")

    # Main benchmark runs
    results: list[BenchmarkResult] = []
    overall_start = time.perf_counter()

    run_data = []
    for i, prompt in enumerate(test_prompts, 1):
        result = benchmark_single_prompt(
            model, tokenizer, prompt, max_tokens, temperature
        )

        if result:
            results.append(result)
            run_data.append(
                [
                    i,
                    result.prompt_tokens,
                    result.generated_tokens,
                    f"{result.ttft*1000:.1f}",
                    f"{result.generation_tps:.1f}",
                ]
            )
            # Sample resources after each run
            monitor.sample()

    overall_time = time.perf_counter() - overall_start

    # Print per-run results table
    print("Per-Run Results:")
    print(
        tabulate(
            run_data,
            headers=["Run", "Input", "Output", "TTFT (ms)", "Gen TPS"],
            tablefmt="simple",
        )
    )
    print()

    if not results:
        print("No successful benchmark runs!")
        return None

    # Calculate summary statistics
    ttfts = [r.ttft for r in results]
    tpots = [r.tpot for r in results if r.tpot > 0]
    latencies = [r.total_time for r in results]
    gen_tps = [r.generation_tps for r in results if r.generation_tps > 0]
    proc_tps = [r.processing_tps for r in results if r.processing_tps > 0]

    total_prompt_tokens = sum(r.prompt_tokens for r in results)
    total_generated_tokens = sum(r.generated_tokens for r in results)
    total_tokens = total_prompt_tokens + total_generated_tokens

    summary = BenchmarkSummary(
        model_name=model_name,
        num_runs=len(results),
        total_prompt_tokens=total_prompt_tokens,
        total_generated_tokens=total_generated_tokens,
        total_time=overall_time,
        ttft_mean=statistics.mean(ttfts),
        ttft_min=min(ttfts),
        ttft_max=max(ttfts),
        ttft_p50=calculate_percentile(ttfts, 50),
        ttft_p95=calculate_percentile(ttfts, 95),
        tpot_mean=statistics.mean(tpots) if tpots else 0,
        tpot_min=min(tpots) if tpots else 0,
        tpot_max=max(tpots) if tpots else 0,
        generation_tps_mean=statistics.mean(gen_tps) if gen_tps else 0,
        generation_tps_max=max(gen_tps) if gen_tps else 0,
        processing_tps_mean=statistics.mean(proc_tps) if proc_tps else 0,
        latency_mean=statistics.mean(latencies),
        latency_min=min(latencies),
        latency_max=max(latencies),
        latency_p50=calculate_percentile(latencies, 50),
        latency_p95=calculate_percentile(latencies, 95),
        total_throughput_tps=total_tokens / overall_time,
        requests_per_second=len(results) / overall_time,
        hardware_chip=hw.chip_name,
        hardware_memory_gb=hw.total_memory_gb,
        hardware_bandwidth_gbs=hw.memory_bandwidth_gbs,
        resources=monitor.get_summary(),
    )

    return summary

vllm_mlx.benchmark.is_mllm_model

is_mllm_model(model_name: str) -> bool

Check if model name indicates a multimodal language model.

Source code in vllm_mlx/benchmark.py
def is_mllm_model(model_name: str) -> bool:
    """Check if model name indicates a multimodal language model."""
    model_lower = model_name.lower()
    for pattern in MLLM_PATTERNS:
        if pattern.lower() in model_lower:
            return True
    return False

vllm_mlx.benchmark.download_test_image

download_test_image(url: str, timeout: int = 30) -> Image

Download image from URL and return PIL Image.

Source code in vllm_mlx/benchmark.py
def download_test_image(url: str, timeout: int = 30) -> Image.Image:
    """Download image from URL and return PIL Image."""
    headers = {
        "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36"
    }
    response = requests.get(url, timeout=timeout, headers=headers)
    response.raise_for_status()
    return Image.open(io.BytesIO(response.content))

vllm_mlx.benchmark.resize_image

resize_image(img: Image, width: int, height: int) -> Image

Resize image to specified dimensions.

Source code in vllm_mlx/benchmark.py
def resize_image(img: Image.Image, width: int, height: int) -> Image.Image:
    """Resize image to specified dimensions."""
    return img.resize((width, height), Image.Resampling.LANCZOS)

vllm_mlx.benchmark.image_to_base64

image_to_base64(img: Image, format: str = 'JPEG') -> str

Convert PIL Image to base64 data URL.

Source code in vllm_mlx/benchmark.py
def image_to_base64(img: Image.Image, format: str = "JPEG") -> str:
    """Convert PIL Image to base64 data URL."""
    if img.mode == "RGBA":
        background = Image.new("RGB", img.size, (255, 255, 255))
        background.paste(img, mask=img.split()[3])
        img = background
    elif img.mode != "RGB":
        img = img.convert("RGB")

    buffer = io.BytesIO()
    img.save(buffer, format=format, quality=85)
    b64 = base64.b64encode(buffer.getvalue()).decode()
    mime = "image/jpeg" if format == "JPEG" else "image/png"
    return f"data:{mime};base64,{b64}"

vllm_mlx.benchmark.benchmark_mllm_resolution

benchmark_mllm_resolution(model, processor, config, base_image: Image, width: int, height: int, max_tokens: int = 256, warmup: bool = False) -> MLLMBenchmarkResult

Run MLLM benchmark for a specific resolution.

Source code in vllm_mlx/benchmark.py
def benchmark_mllm_resolution(
    model,
    processor,
    config,
    base_image: Image.Image,
    width: int,
    height: int,
    max_tokens: int = 256,
    warmup: bool = False,
) -> MLLMBenchmarkResult:
    """Run MLLM benchmark for a specific resolution."""
    from mlx_vlm import generate
    from mlx_vlm.prompt_utils import apply_chat_template

    # Reset MLX peak memory before this run
    reset_mlx_peak_memory()

    # Resize image
    img = resize_image(base_image, width, height)

    # Save to temp file for mlx_vlm
    import tempfile

    temp_file = tempfile.NamedTemporaryFile(suffix=".jpg", delete=False)
    img.save(temp_file.name, "JPEG", quality=85)
    image_path = temp_file.name

    resolution_name = f"{width}x{height}"
    pixels = width * height

    if not warmup:
        print(f"  {resolution_name:>10} | {pixels:>12,} |", end=" ", flush=True)

    # Apply chat template
    prompt = "What animal is in this image? Describe it briefly."
    try:
        formatted_prompt = apply_chat_template(
            processor,
            config,
            prompt,
            num_images=1,
        )
    except Exception:
        formatted_prompt = prompt

    # Generate
    start_time = time.perf_counter()
    result = generate(
        model,
        processor,
        formatted_prompt,
        [image_path],
        max_tokens=max_tokens,
        temp=0.7,
        verbose=False,
    )
    elapsed = time.perf_counter() - start_time

    # Extract text
    if hasattr(result, "text"):
        text = result.text
        tokens = getattr(result, "generation_tokens", len(text.split()))
    else:
        text = str(result)
        tokens = len(text.split())

    tps = tokens / elapsed if elapsed > 0 else 0

    # Get memory metrics
    mlx_info = get_mlx_memory_info()
    process_mem = get_process_memory()

    if not warmup:
        mem_str = f"{mlx_info.get('peak_memory_gb', 0):.1f} GB" if mlx_info else "-"
        print(f"{elapsed:>6.2f}s | {tokens:>6} | {tps:>10.1f} tok/s | {mem_str}")

    # Cleanup
    import os

    os.unlink(image_path)

    return MLLMBenchmarkResult(
        resolution=resolution_name,
        width=width,
        height=height,
        pixels=pixels,
        time_seconds=elapsed,
        tokens_generated=tokens,
        tokens_per_second=tps,
        response_preview=text[:150] + "..." if len(text) > 150 else text,
        memory_gb=process_mem,
        mlx_memory_gb=mlx_info.get("peak_memory_gb", 0.0),
    )

vllm_mlx.benchmark.run_mllm_benchmark

run_mllm_benchmark(model_name: str, quick: bool = False, max_tokens: int = 256, warmup_runs: int = 1) -> list[MLLMBenchmarkResult]

Run MLLM benchmark across multiple image resolutions.

Parameters:

  • model_name (str) –

    HuggingFace model name

  • quick (bool, default: False ) –

    If True, test only 4 resolutions

  • max_tokens (int, default: 256 ) –

    Max tokens to generate

  • warmup_runs (int, default: 1 ) –

    Number of warmup runs

Returns:

Source code in vllm_mlx/benchmark.py
def run_mllm_benchmark(
    model_name: str,
    quick: bool = False,
    max_tokens: int = 256,
    warmup_runs: int = 1,
) -> list[MLLMBenchmarkResult]:
    """
    Run MLLM benchmark across multiple image resolutions.

    Args:
        model_name: HuggingFace model name
        quick: If True, test only 4 resolutions
        max_tokens: Max tokens to generate
        warmup_runs: Number of warmup runs

    Returns:
        List of MLLMBenchmarkResult
    """
    from mlx_vlm import load
    from mlx_vlm.utils import load_config
    from vllm_mlx.optimizations import detect_hardware

    # Detect hardware
    hw = detect_hardware()

    # Define resolutions
    if quick:
        resolutions = [
            (224, 224),
            (448, 448),
            (768, 768),
            (1024, 1024),
        ]
    else:
        resolutions = [
            (224, 224),
            (336, 336),
            (448, 448),
            (512, 512),
            (672, 672),
            (768, 768),
            (896, 896),
            (1024, 1024),
            (1280, 720),
            (1920, 1080),
        ]

    print(f"\n{'='*70}")
    print("vllm-mlx MLLM Performance Benchmark")
    print(f"{'='*70}")

    # Info table
    info_table = [
        ["Model", model_name],
        ["Hardware", f"{hw.chip_name} ({hw.total_memory_gb:.0f} GB)"],
        ["Test Image", "Yellow Labrador (Wikimedia Commons)"],
        ["Resolutions", len(resolutions)],
        ["Max Tokens", max_tokens],
    ]
    print(tabulate(info_table, tablefmt="plain"))
    print(f"{'='*70}\n")

    # Load model
    print(f"Loading MLLM model: {model_name}...")
    load_start = time.perf_counter()
    model, processor = load(model_name)
    config = load_config(model_name)
    load_time = time.perf_counter() - load_start
    print(f"Model loaded in {load_time:.2f}s\n")

    # Download test image
    print("Downloading test image...")
    try:
        base_image = download_test_image(MLLM_TEST_IMAGE_URL)
        print(f"  Original size: {base_image.size[0]}x{base_image.size[1]}\n")
    except Exception as e:
        print(f"Error downloading image: {e}")
        return []

    # Warmup
    if warmup_runs > 0:
        print(f"Running {warmup_runs} warmup run(s)...")
        for _ in range(warmup_runs):
            benchmark_mllm_resolution(
                model, processor, config, base_image, 224, 224, max_tokens, warmup=True
            )

        # Show model memory after warmup (MLX uses lazy evaluation)
        mlx_info = get_mlx_memory_info(reset_peak=True)
        if mlx_info and mlx_info.get("peak_memory_gb", 0) > 0:
            print(f"Model memory: {mlx_info['peak_memory_gb']:.2f} GB (MLX peak)")
        print("Warmup complete.\n")

    # Run benchmarks
    print("-" * 80)
    print(
        f"  {'Resolution':>10} | {'Pixels':>12} | {'Time':>6} | {'Tokens':>6} | {'Speed':>14} | {'Memory':>8}"
    )
    print("-" * 80)

    results = []
    for width, height in resolutions:
        try:
            result = benchmark_mllm_resolution(
                model, processor, config, base_image, width, height, max_tokens
            )
            results.append(result)
        except Exception as e:
            print(f"  Error at {width}x{height}: {e}")

    return results

vllm_mlx.benchmark.print_mllm_summary

print_mllm_summary(results: list[MLLMBenchmarkResult], model_name: str)

Print MLLM benchmark summary.

Source code in vllm_mlx/benchmark.py
def print_mllm_summary(results: list[MLLMBenchmarkResult], model_name: str):
    """Print MLLM benchmark summary."""
    if not results:
        print("No results to display.")
        return

    print(f"\n{'='*80}")
    print("MLLM BENCHMARK RESULTS")
    print(f"{'='*80}\n")

    # Results table
    table_data = []
    for r in results:
        table_data.append(
            [
                r.resolution,
                f"{r.pixels:,}",
                f"{r.time_seconds:.2f}s",
                r.tokens_generated,
                f"{r.tokens_per_second:.1f}",
                (
                    f"{r.pixels / r.time_seconds / 1000:.1f}K"
                    if r.time_seconds > 0
                    else "N/A"
                ),
                f"{r.mlx_memory_gb:.2f}" if r.mlx_memory_gb > 0 else "-",
            ]
        )

    headers = [
        "Resolution",
        "Pixels",
        "Time",
        "Tokens",
        "Tok/s",
        "Pixels/s",
        "Mem (GB)",
    ]
    print(tabulate(table_data, headers=headers, tablefmt="simple"))

    # Summary stats
    total_time = sum(r.time_seconds for r in results)
    total_tokens = sum(r.tokens_generated for r in results)
    avg_tps = total_tokens / total_time if total_time > 0 else 0
    peak_memory = max(r.mlx_memory_gb for r in results) if results else 0

    print("-" * 80)
    print(f"Total Time:      {total_time:.2f}s")
    print(f"Total Tokens:    {total_tokens}")
    print(f"Average Tok/s:   {avg_tps:.1f}")
    if peak_memory > 0:
        print(f"Peak Memory:     {peak_memory:.2f} GB")

    fastest = min(results, key=lambda r: r.time_seconds)
    slowest = max(results, key=lambda r: r.time_seconds)

    print(f"\nFastest:  {fastest.resolution} ({fastest.time_seconds:.2f}s)")
    print(f"Slowest:  {slowest.resolution} ({slowest.time_seconds:.2f}s)")
    print(f"Slowdown: {slowest.time_seconds / fastest.time_seconds:.1f}x")
    print(f"{'='*80}")

vllm_mlx.benchmark.create_test_video

create_test_video(duration: float = 10.0, fps: float = 30.0, width: int = 640, height: int = 480) -> str

Create a synthetic test video with colored frames and text.

Source code in vllm_mlx/benchmark.py
def create_test_video(
    duration: float = 10.0,
    fps: float = 30.0,
    width: int = 640,
    height: int = 480,
) -> str:
    """Create a synthetic test video with colored frames and text."""
    temp_file = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False)
    temp_file.close()

    fourcc = cv2.VideoWriter_fourcc(*"mp4v")
    out = cv2.VideoWriter(temp_file.name, fourcc, fps, (width, height))

    total_frames = int(duration * fps)

    scenes = [
        ((255, 0, 0), "Blue Scene"),
        ((0, 255, 0), "Green Scene"),
        ((0, 0, 255), "Red Scene"),
        ((255, 255, 0), "Cyan Scene"),
        ((255, 0, 255), "Magenta Scene"),
        ((0, 255, 255), "Yellow Scene"),
    ]

    frames_per_scene = total_frames // len(scenes)

    for i in range(total_frames):
        frame = np.zeros((height, width, 3), dtype=np.uint8)
        scene_idx = min(i // frames_per_scene, len(scenes) - 1)
        color, scene_name = scenes[scene_idx]
        frame[:] = color

        cv2.putText(
            frame,
            scene_name,
            (width // 4, height // 2 - 30),
            cv2.FONT_HERSHEY_SIMPLEX,
            1.5,
            (255, 255, 255),
            3,
        )
        cv2.putText(
            frame,
            f"Frame {i}/{total_frames}",
            (width // 4, height // 2 + 30),
            cv2.FONT_HERSHEY_SIMPLEX,
            1.0,
            (255, 255, 255),
            2,
        )

        out.write(frame)

    out.release()
    return temp_file.name

vllm_mlx.benchmark.download_video

download_video(url: str, timeout: int = 120) -> str

Download video from URL and return local path.

Source code in vllm_mlx/benchmark.py
def download_video(url: str, timeout: int = 120) -> str:
    """Download video from URL and return local path."""
    headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)"}

    print(f"  Downloading video from: {url[:60]}...")
    response = requests.get(url, timeout=timeout, headers=headers, stream=True)
    response.raise_for_status()

    temp_file = tempfile.NamedTemporaryFile(suffix=".mp4", delete=False)
    for chunk in response.iter_content(chunk_size=8192):
        temp_file.write(chunk)
    temp_file.close()

    file_size = Path(temp_file.name).stat().st_size
    print(f"  Downloaded: {file_size / 1024 / 1024:.1f} MB")

    return temp_file.name

vllm_mlx.benchmark.get_video_info

get_video_info(video_path: str) -> dict

Get information about a video file.

Source code in vllm_mlx/benchmark.py
def get_video_info(video_path: str) -> dict:
    """Get information about a video file."""
    cap = cv2.VideoCapture(video_path)
    if not cap.isOpened():
        return {"error": "Cannot open video"}

    info = {
        "path": video_path,
        "total_frames": int(cap.get(cv2.CAP_PROP_FRAME_COUNT)),
        "fps": cap.get(cv2.CAP_PROP_FPS) or 30.0,
        "width": int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
        "height": int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)),
    }
    info["duration"] = info["total_frames"] / info["fps"] if info["fps"] > 0 else 0

    cap.release()
    return info

vllm_mlx.benchmark.benchmark_video_config

benchmark_video_config(model, video_path: str, fps: float, max_frames: int, config_name: str, video_info: dict, max_tokens: int = 150, warmup: bool = False) -> VideoBenchmarkResult

Run a single video benchmark configuration.

Source code in vllm_mlx/benchmark.py
def benchmark_video_config(
    model,
    video_path: str,
    fps: float,
    max_frames: int,
    config_name: str,
    video_info: dict,
    max_tokens: int = 150,
    warmup: bool = False,
) -> VideoBenchmarkResult:
    """Run a single video benchmark configuration."""

    # Reset MLX peak memory before this run
    reset_mlx_peak_memory()

    if not warmup:
        print(f"  {config_name:>25} |", end=" ", flush=True)

    start_time = time.perf_counter()

    output = model.generate(
        prompt="Describe what happens in this video. What do you see?",
        videos=[video_path],
        video_fps=fps,
        video_max_frames=max_frames,
        max_tokens=max_tokens,
        temperature=0.7,
    )

    elapsed = time.perf_counter() - start_time

    prompt_tokens = output.prompt_tokens
    completion_tokens = output.completion_tokens
    tps = completion_tokens / elapsed if elapsed > 0 else 0

    # Estimate frames extracted
    duration = video_info["duration"]
    frames_from_fps = int(duration * fps)
    frames_extracted = min(frames_from_fps, max_frames, video_info["total_frames"])

    # Get memory metrics
    mlx_info = get_mlx_memory_info()
    process_mem = get_process_memory()

    if not warmup:
        mem_str = f"{mlx_info.get('peak_memory_gb', 0):.1f} GB" if mlx_info else "-"
        print(
            f"{frames_extracted:>2} frames | {elapsed:>5.2f}s | {completion_tokens:>3} tok | {tps:>6.1f} tok/s | {mem_str}"
        )

    return VideoBenchmarkResult(
        config_name=config_name,
        fps=fps,
        max_frames=max_frames,
        frames_extracted=frames_extracted,
        video_duration=duration,
        time_seconds=elapsed,
        prompt_tokens=prompt_tokens,
        completion_tokens=completion_tokens,
        tokens_per_second=tps,
        response_preview=(
            output.text[:100] + "..." if len(output.text) > 100 else output.text
        ),
        memory_gb=process_mem,
        mlx_memory_gb=mlx_info.get("peak_memory_gb", 0.0),
    )

vllm_mlx.benchmark.run_video_benchmark

run_video_benchmark(model_name: str, video_url: str = None, video_path: str = None, quick: bool = False, max_tokens: int = 150, warmup_runs: int = 1) -> list[VideoBenchmarkResult]

Run video benchmark across multiple frame configurations.

Parameters:

  • model_name (str) –

    HuggingFace MLLM model name

  • video_url (str, default: None ) –

    URL to download video from

  • video_path (str, default: None ) –

    Local video file path

  • quick (bool, default: False ) –

    If True, test only 3 configurations

  • max_tokens (int, default: 150 ) –

    Max tokens to generate

  • warmup_runs (int, default: 1 ) –

    Number of warmup runs

Returns:

Source code in vllm_mlx/benchmark.py
def run_video_benchmark(
    model_name: str,
    video_url: str = None,
    video_path: str = None,
    quick: bool = False,
    max_tokens: int = 150,
    warmup_runs: int = 1,
) -> list[VideoBenchmarkResult]:
    """
    Run video benchmark across multiple frame configurations.

    Args:
        model_name: HuggingFace MLLM model name
        video_url: URL to download video from
        video_path: Local video file path
        quick: If True, test only 3 configurations
        max_tokens: Max tokens to generate
        warmup_runs: Number of warmup runs

    Returns:
        List of VideoBenchmarkResult
    """
    from vllm_mlx.models.mllm import MLXMultimodalLM
    from vllm_mlx.optimizations import detect_hardware

    # Detect hardware
    hw = detect_hardware()

    # Define configurations: (name, fps, max_frames)
    if quick:
        configs = [
            ("4 frames @ 1fps", 1.0, 4),
            ("8 frames @ 2fps", 2.0, 8),
            ("16 frames @ 2fps", 2.0, 16),
        ]
    else:
        configs = [
            # Varying frame counts (from 2 to 64 frames)
            # Note: 96+ frames causes GPU timeout on most hardware
            ("2 frames @ 0.5fps", 0.5, 2),
            ("4 frames @ 1fps", 1.0, 4),
            ("6 frames @ 1fps", 1.0, 6),
            ("8 frames @ 2fps", 2.0, 8),
            ("12 frames @ 2fps", 2.0, 12),
            ("16 frames @ 2fps", 2.0, 16),
            ("24 frames @ 4fps", 4.0, 24),
            ("32 frames @ 4fps", 4.0, 32),
            ("48 frames @ 8fps", 8.0, 48),
            ("64 frames @ 8fps", 8.0, 64),
        ]

    print(f"\n{'='*70}")
    print("vllm-mlx Video Performance Benchmark")
    print(f"{'='*70}")

    # Info table
    info_table = [
        ["Model", model_name],
        ["Hardware", f"{hw.chip_name} ({hw.total_memory_gb:.0f} GB)"],
        ["Configurations", len(configs)],
        ["Max Tokens", max_tokens],
    ]
    print(tabulate(info_table, tablefmt="plain"))
    print(f"{'='*70}\n")

    # Load model
    print(f"Loading MLLM model: {model_name}...")
    load_start = time.perf_counter()
    model = MLXMultimodalLM(model_name)
    model.load()
    load_time = time.perf_counter() - load_start
    print(f"Model loaded in {load_time:.2f}s\n")

    # Get or create video
    if video_path and Path(video_path).exists():
        print(f"Using local video: {video_path}")
    elif video_url:
        video_path = download_video(video_url)
    else:
        print("Downloading default test video (Big Buck Bunny 10s)...")
        video_path = download_video(DEFAULT_VIDEO_URL)

    video_info = get_video_info(video_path)
    print(
        f"\nVideo: {video_info['width']}x{video_info['height']}, "
        f"{video_info['duration']:.1f}s, {video_info['fps']:.1f} fps, "
        f"{video_info['total_frames']} frames\n"
    )

    # Warmup
    if warmup_runs > 0:
        print(f"Running {warmup_runs} warmup run(s)...")
        for _ in range(warmup_runs):
            benchmark_video_config(
                model, video_path, 1.0, 4, "warmup", video_info, max_tokens, warmup=True
            )

        # Show model memory after warmup (MLX uses lazy evaluation)
        mlx_info = get_mlx_memory_info(reset_peak=True)
        if mlx_info and mlx_info.get("peak_memory_gb", 0) > 0:
            print(f"Model memory: {mlx_info['peak_memory_gb']:.2f} GB (MLX peak)")
        print("Warmup complete.\n")

    # Run benchmarks
    print("-" * 85)
    print(
        f"  {'Configuration':>25} | {'Frames':>6} | {'Time':>6} | {'Tokens':>4} | {'Speed':>10} | {'Memory':>8}"
    )
    print("-" * 85)

    results = []
    for config_name, fps, max_frames in configs:
        try:
            result = benchmark_video_config(
                model, video_path, fps, max_frames, config_name, video_info, max_tokens
            )
            results.append(result)
        except Exception as e:
            print(f"  Error with {config_name}: {e}")

    return results

vllm_mlx.benchmark.print_video_summary

print_video_summary(results: list[VideoBenchmarkResult], model_name: str)

Print video benchmark summary.

Source code in vllm_mlx/benchmark.py
def print_video_summary(results: list[VideoBenchmarkResult], model_name: str):
    """Print video benchmark summary."""
    if not results:
        print("No results to display.")
        return

    print(f"\n{'='*85}")
    print("VIDEO BENCHMARK RESULTS")
    print(f"{'='*85}\n")

    # Results table
    table_data = []
    for r in sorted(results, key=lambda x: x.frames_extracted):
        table_data.append(
            [
                r.config_name,
                r.frames_extracted,
                f"{r.time_seconds:.2f}s",
                r.completion_tokens,
                f"{r.tokens_per_second:.1f}",
                f"{r.mlx_memory_gb:.2f}" if r.mlx_memory_gb > 0 else "-",
            ]
        )

    headers = ["Configuration", "Frames", "Time", "Tokens", "Tok/s", "Mem (GB)"]
    print(tabulate(table_data, headers=headers, tablefmt="simple"))

    # Summary stats
    total_time = sum(r.time_seconds for r in results)
    total_tokens = sum(r.completion_tokens for r in results)
    avg_tps = total_tokens / total_time if total_time > 0 else 0
    peak_memory = max(r.mlx_memory_gb for r in results) if results else 0

    print("-" * 85)
    print(f"Total Time:      {total_time:.2f}s")
    print(f"Total Tokens:    {total_tokens}")
    print(f"Average Tok/s:   {avg_tps:.1f}")
    if peak_memory > 0:
        print(f"Peak Memory:     {peak_memory:.2f} GB")

    fastest = min(results, key=lambda r: r.time_seconds)
    slowest = max(results, key=lambda r: r.time_seconds)
    most_frames = max(results, key=lambda r: r.frames_extracted)

    print(
        f"\nFastest:     {fastest.config_name} ({fastest.time_seconds:.2f}s, {fastest.tokens_per_second:.1f} tok/s)"
    )
    print(
        f"Slowest:     {slowest.config_name} ({slowest.time_seconds:.2f}s, {slowest.tokens_per_second:.1f} tok/s)"
    )
    print(
        f"Most Frames: {most_frames.config_name} ({most_frames.frames_extracted} frames)"
    )
    print(f"{'='*85}")

vllm_mlx.benchmark.print_summary

print_summary(summary: BenchmarkSummary)

Print a formatted summary of benchmark results using tabulate.

Source code in vllm_mlx/benchmark.py
def print_summary(summary: BenchmarkSummary):
    """Print a formatted summary of benchmark results using tabulate."""
    print(f"\n{'='*60}")
    print("BENCHMARK RESULTS")
    print(f"{'='*60}\n")

    # Overview table
    overview_data = [
        ["Model", summary.model_name],
        ["Hardware", f"{summary.hardware_chip} ({summary.hardware_memory_gb:.0f} GB)"],
        ["Total Runs", summary.num_runs],
        ["Input Tokens", f"{summary.total_prompt_tokens:,}"],
        ["Output Tokens", f"{summary.total_generated_tokens:,}"],
        ["Total Time", f"{summary.total_time:.2f}s"],
    ]
    print(tabulate(overview_data, tablefmt="plain"))
    print()

    # Main metrics table
    metrics_data = [
        [
            "TTFT (Time to First Token)",
            f"{summary.ttft_mean*1000:.1f} ms",
            f"{summary.ttft_p95*1000:.1f} ms",
        ],
        [
            "TPOT (Time Per Output Token)",
            f"{summary.tpot_mean*1000:.2f} ms",
            f"{summary.tpot_max*1000:.2f} ms",
        ],
        [
            "Generation Speed",
            f"{summary.generation_tps_mean:.1f} tok/s",
            f"{summary.generation_tps_max:.1f} tok/s",
        ],
        ["Processing Speed", f"{summary.processing_tps_mean:.1f} tok/s", "-"],
        [
            "Latency (per request)",
            f"{summary.latency_mean:.2f}s",
            f"{summary.latency_p95:.2f}s",
        ],
    ]
    print("Performance Metrics:")
    print(
        tabulate(
            metrics_data,
            headers=["Metric", "Mean", "P95/Max"],
            tablefmt="simple",
        )
    )
    print()

    # Throughput table
    throughput_data = [
        ["Total Throughput", f"{summary.total_throughput_tps:.1f} tok/s"],
        ["Requests/Second", f"{summary.requests_per_second:.2f} req/s"],
    ]
    print("Throughput:")
    print(tabulate(throughput_data, tablefmt="plain"))
    print()

    # Resource metrics
    res = summary.resources
    if res.process_memory_gb > 0 or res.mlx_peak_memory_gb > 0:
        print("Resource Usage:")
        resource_data = []

        if res.process_memory_gb > 0:
            resource_data.append(
                ["Process Memory (peak)", f"{res.process_memory_gb:.2f} GB"]
            )

        if res.mlx_peak_memory_gb > 0:
            resource_data.append(
                ["MLX Peak Memory", f"{res.mlx_peak_memory_gb:.2f} GB"]
            )

        if res.mlx_cache_gb > 0:
            resource_data.append(["MLX Cache Memory", f"{res.mlx_cache_gb:.2f} GB"])

        if res.system_memory_total_gb > 0:
            used_pct = (res.system_memory_used_gb / res.system_memory_total_gb) * 100
            resource_data.append(
                [
                    "System Memory",
                    f"{res.system_memory_used_gb:.1f} / {res.system_memory_total_gb:.0f} GB ({used_pct:.0f}%)",
                ]
            )

        print(tabulate(resource_data, tablefmt="plain"))
        print()

    print(f"{'='*60}")

vllm_mlx.benchmark.main

main()

Run the benchmark.

Source code in vllm_mlx/benchmark.py
def main():
    """Run the benchmark."""
    parser = argparse.ArgumentParser(
        description="vllm-mlx Performance Benchmark (LLM, MLLM Image & Video)",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
Examples:
    # LLM benchmark
    vllm-mlx-bench --model mlx-community/Llama-3.2-1B-Instruct-4bit
    vllm-mlx-bench --model mlx-community/Llama-3.2-3B-Instruct-4bit --prompts 10

    # MLLM image benchmark (auto-detected)
    vllm-mlx-bench --model mlx-community/Qwen3-VL-4B-Instruct-3bit
    vllm-mlx-bench --model mlx-community/Qwen3-VL-4B-Instruct-3bit --quick

    # MLLM video benchmark
    vllm-mlx-bench --model mlx-community/Qwen3-VL-4B-Instruct-3bit --video
    vllm-mlx-bench --model mlx-community/Qwen3-VL-4B-Instruct-3bit --video --quick
    vllm-mlx-bench --model mlx-community/Qwen3-VL-4B-Instruct-3bit --video --video-url https://example.com/video.mp4

    # Force MLLM mode
    vllm-mlx-bench --model custom-vision-model --mllm
        """,
    )
    parser.add_argument(
        "--model",
        type=str,
        required=True,
        help="Model name (HuggingFace model name or local path)",
    )
    parser.add_argument(
        "--prompts",
        type=int,
        default=5,
        help="Number of prompts to benchmark for LLM (default: 5)",
    )
    parser.add_argument(
        "--max-tokens",
        type=int,
        default=256,
        help="Maximum tokens to generate per prompt (default: 256)",
    )
    parser.add_argument(
        "--temperature",
        type=float,
        default=0.7,
        help="Sampling temperature (default: 0.7)",
    )
    parser.add_argument(
        "--warmup",
        type=int,
        default=1,
        help="Number of warmup runs (default: 1)",
    )
    parser.add_argument(
        "--output",
        type=str,
        default=None,
        help="Output file for JSON results",
    )
    parser.add_argument(
        "--mllm",
        action="store_true",
        help="Force MLLM benchmark mode (auto-detected by default)",
    )
    parser.add_argument(
        "--quick",
        action="store_true",
        help="Quick benchmark with fewer configurations",
    )
    # Video benchmark arguments
    parser.add_argument(
        "--video",
        action="store_true",
        help="Run video benchmark instead of image benchmark (for MLLM models)",
    )
    parser.add_argument(
        "--video-url",
        type=str,
        default=None,
        help="URL of video to use for benchmark (default: Big Buck Bunny 10s)",
    )
    parser.add_argument(
        "--video-path",
        type=str,
        default=None,
        help="Local path to video file for benchmark",
    )

    args = parser.parse_args()

    # Determine if MLLM model
    run_mllm = args.mllm or is_mllm_model(args.model)

    if args.video:
        # Video Benchmark
        results = run_video_benchmark(
            model_name=args.model,
            video_url=args.video_url,
            video_path=args.video_path,
            quick=args.quick,
            max_tokens=args.max_tokens,
            warmup_runs=args.warmup,
        )

        if results:
            print_video_summary(results, args.model)

            # Save to JSON if requested
            if args.output:
                with open(args.output, "w") as f:
                    json.dump(
                        {
                            "type": "video",
                            "model": args.model,
                            "test_video": args.video_url
                            or args.video_path
                            or "Big Buck Bunny 10s",
                            "results": [
                                {
                                    "config_name": r.config_name,
                                    "fps": r.fps,
                                    "max_frames": r.max_frames,
                                    "frames_extracted": r.frames_extracted,
                                    "video_duration": r.video_duration,
                                    "time_seconds": r.time_seconds,
                                    "prompt_tokens": r.prompt_tokens,
                                    "completion_tokens": r.completion_tokens,
                                    "tokens_per_second": r.tokens_per_second,
                                    "response_preview": r.response_preview,
                                }
                                for r in results
                            ],
                        },
                        f,
                        indent=2,
                    )
                print(f"\nResults saved to: {args.output}")

    elif run_mllm:
        # MLLM Image Benchmark
        results = run_mllm_benchmark(
            model_name=args.model,
            quick=args.quick,
            max_tokens=args.max_tokens,
            warmup_runs=args.warmup,
        )

        if results:
            print_mllm_summary(results, args.model)

            # Save to JSON if requested
            if args.output:
                with open(args.output, "w") as f:
                    json.dump(
                        {
                            "type": "mllm_image",
                            "model": args.model,
                            "test_image": "Yellow Labrador (Wikimedia Commons)",
                            "results": [
                                {
                                    "resolution": r.resolution,
                                    "width": r.width,
                                    "height": r.height,
                                    "pixels": r.pixels,
                                    "time_seconds": r.time_seconds,
                                    "tokens_generated": r.tokens_generated,
                                    "tokens_per_second": r.tokens_per_second,
                                    "response_preview": r.response_preview,
                                }
                                for r in results
                            ],
                        },
                        f,
                        indent=2,
                    )
                print(f"\nResults saved to: {args.output}")
    else:
        # LLM Benchmark
        summary = run_benchmark(
            model_name=args.model,
            num_prompts=args.prompts,
            max_tokens=args.max_tokens,
            temperature=args.temperature,
            warmup_runs=args.warmup,
        )

        if summary:
            print_summary(summary)

            # Save to JSON if requested
            if args.output:
                with open(args.output, "w") as f:
                    json.dump(
                        {
                            "type": "llm",
                            "model": summary.model_name,
                            "hardware": {
                                "chip": summary.hardware_chip,
                                "memory_gb": summary.hardware_memory_gb,
                                "bandwidth_gbs": summary.hardware_bandwidth_gbs,
                            },
                            "num_runs": summary.num_runs,
                            "total_prompt_tokens": summary.total_prompt_tokens,
                            "total_generated_tokens": summary.total_generated_tokens,
                            "total_time_seconds": summary.total_time,
                            "ttft_ms": {
                                "mean": summary.ttft_mean * 1000,
                                "min": summary.ttft_min * 1000,
                                "max": summary.ttft_max * 1000,
                                "p50": summary.ttft_p50 * 1000,
                                "p95": summary.ttft_p95 * 1000,
                            },
                            "tpot_ms": {
                                "mean": summary.tpot_mean * 1000,
                                "min": summary.tpot_min * 1000,
                                "max": summary.tpot_max * 1000,
                            },
                            "tokens_per_second": {
                                "generation_mean": summary.generation_tps_mean,
                                "generation_max": summary.generation_tps_max,
                                "processing_mean": summary.processing_tps_mean,
                                "total_throughput": summary.total_throughput_tps,
                            },
                            "latency_seconds": {
                                "mean": summary.latency_mean,
                                "min": summary.latency_min,
                                "max": summary.latency_max,
                                "p50": summary.latency_p50,
                                "p95": summary.latency_p95,
                            },
                            "requests_per_second": summary.requests_per_second,
                        },
                        f,
                        indent=2,
                    )
                print(f"\nResults saved to: {args.output}")

Complete contract reference

Expand any definition for its exact inputs, annotations, defaults, return contract, directly raised exceptions, source-grounded behavior, and immutable line link. This section includes private and nested definitions that ordinary API generators omit.

vllm_mlx.benchmark.ResourceMetrics · class
vllm_mlx.benchmark.ResourceMetrics(process_memory_gb: float = 0.0, mlx_cache_gb: float = 0.0, mlx_peak_memory_gb: float = 0.0, system_memory_used_gb: float = 0.0, system_memory_total_gb: float = 0.0)

Resource usage metrics during benchmark.

Parameters

Name Type Required Default Description
process_memory_gb float no 0.0 Optional constructor field; defaults to 0.0.
mlx_cache_gb float no 0.0 Optional constructor field; defaults to 0.0.
mlx_peak_memory_gb float no 0.0 Optional constructor field; defaults to 0.0.
system_memory_used_gb float no 0.0 Optional constructor field; defaults to 0.0.
system_memory_total_gb float no 0.0 Optional constructor field; defaults to 0.0.

Returns

  • Constructs: vllm_mlx.benchmark.ResourceMetrics

Exceptions and behavior

Class ResourceMetrics declares 0 direct member(s). No direct raise statement appears in this definition.

View source #L72-L80.

vllm_mlx.benchmark.reset_mlx_peak_memory · function
vllm_mlx.benchmark.reset_mlx_peak_memory() -> not annotated

Reset MLX peak memory counter.

Parameters

This callable has no explicit inputs.

Returns

  • Type: not annotated
  • Direct return expressions: None

Exceptions and behavior

Function reset_mlx_peak_memory calls hasattr, mx.reset_peak_memory, mx.metal.reset_peak_memory; returns None. No direct raise statement appears in this definition.

View source #L83-L95.

vllm_mlx.benchmark.get_mlx_memory_info · function
vllm_mlx.benchmark.get_mlx_memory_info(reset_peak: bool = True) -> dict

Get MLX memory usage information.

Parameters

Name Type Required Default Description
reset_peak bool no True If True, reset peak memory counter after reading.

Returns

  • Type: dict
  • Direct return expressions: {}; info

Exceptions and behavior

Function get_mlx_memory_info calls hasattr, mx.get_cache_memory, mx.get_peak_memory, mx.get_active_memory; has 2 explicit return paths. No direct raise statement appears in this definition.

View source #L98-L135.

vllm_mlx.benchmark.get_process_memory · function
vllm_mlx.benchmark.get_process_memory() -> float

Get current process memory usage in GB.

Parameters

This callable has no explicit inputs.

Returns

  • Type: float
  • Direct return expressions: 0.0; process.memory_info().rss / 1024 ** 3

Exceptions and behavior

Function get_process_memory calls psutil.Process, process.memory_info; has 2 explicit return paths. No direct raise statement appears in this definition.

View source #L138-L147.

vllm_mlx.benchmark.get_system_memory · function
vllm_mlx.benchmark.get_system_memory() -> tuple[float, float]

Get system memory (used, total) in GB.

Parameters

This callable has no explicit inputs.

Returns

  • Type: tuple[float, float]
  • Direct return expressions: (0.0, 0.0); (mem.used / 1024 ** 3, mem.total / 1024 ** 3)

Exceptions and behavior

Function get_system_memory calls psutil.virtual_memory; has 2 explicit return paths. No direct raise statement appears in this definition.

View source #L150-L159.

vllm_mlx.benchmark.ResourceMonitor · class
vllm_mlx.benchmark.ResourceMonitor()

Monitor system resources during benchmark runs.

Parameters

This callable has no explicit inputs.

Returns

  • Constructs: vllm_mlx.benchmark.ResourceMonitor

Exceptions and behavior

Class ResourceMonitor declares 4 direct member(s). No direct raise statement appears in this definition.

View source #L162-L213.

vllm_mlx.benchmark.ResourceMonitor.__init__ · method
vllm_mlx.benchmark.ResourceMonitor.__init__() -> not annotated

Method ResourceMonitor.__init__ updates self.samples, self._start_time, self._start_memory.

Parameters

This callable has no explicit inputs.

Returns

  • Type: not annotated

Exceptions and behavior

Method ResourceMonitor.__init__ updates self.samples, self._start_time, self._start_memory. No direct raise statement appears in this definition.

View source #L165-L168.

vllm_mlx.benchmark.ResourceMonitor.start · method
vllm_mlx.benchmark.ResourceMonitor.start() -> not annotated

Start monitoring.

Parameters

This callable has no explicit inputs.

Returns

  • Type: not annotated

Exceptions and behavior

Method ResourceMonitor.start updates self._start_time, self._start_memory; calls time.perf_counter, get_process_memory, reset_mlx_peak_memory. No direct raise statement appears in this definition.

View source #L170-L176.

vllm_mlx.benchmark.ResourceMonitor.sample · method
vllm_mlx.benchmark.ResourceMonitor.sample() -> ResourceMetrics

Take a resource sample.

Parameters

This callable has no explicit inputs.

Returns

  • Type: ResourceMetrics
  • Direct return expressions: metrics

Exceptions and behavior

Method ResourceMonitor.sample calls get_mlx_memory_info, get_system_memory, ResourceMetrics, get_process_memory; returns metrics. No direct raise statement appears in this definition.

View source #L178-L192.

vllm_mlx.benchmark.ResourceMonitor.get_summary · method
vllm_mlx.benchmark.ResourceMonitor.get_summary() -> ResourceMetrics

Get summary of all samples.

Parameters

This callable has no explicit inputs.

Returns

  • Type: ResourceMetrics
  • Direct return expressions: ResourceMetrics(); ResourceMetrics(process_memory_gb=peak_process, mlx_cache_gb=peak_mlx_cache, mlx_peak_memory_gb=peak_mlx, system_memory…

Exceptions and behavior

Method ResourceMonitor.get_summary calls ResourceMetrics, max; has 2 explicit return paths. No direct raise statement appears in this definition.

View source #L194-L213.

vllm_mlx.benchmark.BenchmarkResult · class
vllm_mlx.benchmark.BenchmarkResult(prompt: str, prompt_tokens: int, generated_tokens: int, ttft: float, total_time: float, tpot: float = 0.0, generation_tps: float = 0.0, processing_tps: float = 0.0)

Results from a single benchmark run.

Parameters

Name Type Required Default Description
prompt str yes none Required constructor field.
prompt_tokens int yes none Required constructor field.
generated_tokens int yes none Required constructor field.
ttft float yes none Required constructor field.
total_time float yes none Required constructor field.
tpot float no 0.0 Optional constructor field; defaults to 0.0.
generation_tps float no 0.0 Optional constructor field; defaults to 0.0.
processing_tps float no 0.0 Optional constructor field; defaults to 0.0.

Returns

  • Constructs: vllm_mlx.benchmark.BenchmarkResult

Exceptions and behavior

Class BenchmarkResult declares 1 direct member(s). No direct raise statement appears in this definition.

View source #L235-L268.

vllm_mlx.benchmark.BenchmarkResult.__post_init__ · method
vllm_mlx.benchmark.BenchmarkResult.__post_init__() -> not annotated

Method BenchmarkResult.__post_init__ updates self.tpot, self.generation_tps, self.processing_tps.

Parameters

This callable has no explicit inputs.

Returns

  • Type: not annotated

Exceptions and behavior

Method BenchmarkResult.__post_init__ updates self.tpot, self.generation_tps, self.processing_tps. No direct raise statement appears in this definition.

View source #L251-L268.

vllm_mlx.benchmark.BenchmarkSummary · class
vllm_mlx.benchmark.BenchmarkSummary(model_name: str, num_runs: int, total_prompt_tokens: int, total_generated_tokens: int, total_time: float, ttft_mean: float, ttft_min: float, ttft_max: float, ttft_p50: float, ttft_p95: float, tpot_mean: float, tpot_min: float, tpot_max: float, generation_tps_mean: float, generation_tps_max: float, processing_tps_mean: float, latency_mean: float, latency_min: float, latency_max: float, latency_p50: float, latency_p95: float, total_throughput_tps: float, requests_per_second: float, hardware_chip: str = '', hardware_memory_gb: float = 0.0, hardware_bandwidth_gbs: float = 0.0, resources: ResourceMetrics = field(default_factory=ResourceMetrics))

Summary statistics across all benchmark runs.

Parameters

Name Type Required Default Description
model_name str yes none Required constructor field.
num_runs int yes none Required constructor field.
total_prompt_tokens int yes none Required constructor field.
total_generated_tokens int yes none Required constructor field.
total_time float yes none Required constructor field.
ttft_mean float yes none Required constructor field.
ttft_min float yes none Required constructor field.
ttft_max float yes none Required constructor field.
ttft_p50 float yes none Required constructor field.
ttft_p95 float yes none Required constructor field.
tpot_mean float yes none Required constructor field.
tpot_min float yes none Required constructor field.
tpot_max float yes none Required constructor field.
generation_tps_mean float yes none Required constructor field.
generation_tps_max float yes none Required constructor field.
processing_tps_mean float yes none Required constructor field.
latency_mean float yes none Required constructor field.
latency_min float yes none Required constructor field.
latency_max float yes none Required constructor field.
latency_p50 float yes none Required constructor field.
latency_p95 float yes none Required constructor field.
total_throughput_tps float yes none Required constructor field.
requests_per_second float yes none Required constructor field.
hardware_chip str no '' Optional constructor field; defaults to ''.
hardware_memory_gb float no 0.0 Optional constructor field; defaults to 0.0.
hardware_bandwidth_gbs float no 0.0 Optional constructor field; defaults to 0.0.
resources ResourceMetrics no field(default_factory=ResourceMetrics) Optional constructor field; defaults to field(default_factory=ResourceMetrics).

Returns

  • Constructs: vllm_mlx.benchmark.BenchmarkSummary

Exceptions and behavior

Class BenchmarkSummary declares 0 direct member(s). No direct raise statement appears in this definition.

View source #L272-L315.

vllm_mlx.benchmark.calculate_percentile · function
vllm_mlx.benchmark.calculate_percentile(data: list, percentile: float) -> float

Calculate percentile from a list.

Parameters

Name Type Required Default Description
data list yes none Required positional or keyword input.
percentile float yes none Required positional or keyword input.

Returns

  • Type: float
  • Direct return expressions: 0.0; sorted_data[index]

Exceptions and behavior

Function calculate_percentile calls sorted, int, len, min; has 2 explicit return paths. No direct raise statement appears in this definition.

View source #L318-L325.

vllm_mlx.benchmark.benchmark_single_prompt · function
vllm_mlx.benchmark.benchmark_single_prompt(model, tokenizer, prompt: str, max_tokens: int = 256, temperature: float = 0.7) -> Optional[BenchmarkResult]

Benchmark a single prompt with detailed timing.

Parameters

Name Type Required Default Description
model not annotated yes none The loaded MLX model
tokenizer not annotated yes none The tokenizer
prompt str yes none The prompt to benchmark
max_tokens int no 256 Maximum tokens to generate
temperature float no 0.7 Sampling temperature

Returns

  • Type: Optional[BenchmarkResult]
  • Direct return expressions: BenchmarkResult(prompt=prompt[:50] + '...' if len(prompt) > 50 else prompt, prompt_tokens=prompt_token_count, generated…; None

Exceptions and behavior

Function benchmark_single_prompt calls tokenizer.encode, len, make_sampler, time.perf_counter; has 2 explicit return paths. No direct raise statement appears in this definition.

View source #L328-L394.

vllm_mlx.benchmark.run_benchmark · function
vllm_mlx.benchmark.run_benchmark(model_name: str, num_prompts: int = 5, max_tokens: int = 256, temperature: float = 0.7, warmup_runs: int = 1) -> Optional[BenchmarkSummary]

Run the full benchmark suite.

Parameters

Name Type Required Default Description
model_name str yes none HuggingFace model name or local path
num_prompts int no 5 Number of prompts to test
max_tokens int no 256 Maximum tokens per generation
temperature float no 0.7 Sampling temperature
warmup_runs int no 1 Number of warmup runs before measuring

Returns

  • Type: Optional[BenchmarkSummary]
  • Direct return expressions: None; summary

Exceptions and behavior

Function run_benchmark calls detect_hardware, len, print, tabulate; has 2 explicit return paths. No direct raise statement appears in this definition.

View source #L397-L610.

vllm_mlx.benchmark.is_mllm_model · function
vllm_mlx.benchmark.is_mllm_model(model_name: str) -> bool

Check if model name indicates a multimodal language model.

Parameters

Name Type Required Default Description
model_name str yes none Required positional or keyword input.

Returns

  • Type: bool
  • Direct return expressions: True; False

Exceptions and behavior

Function is_mllm_model calls model_name.lower, pattern.lower; has 2 explicit return paths. No direct raise statement appears in this definition.

View source #L651-L657.

vllm_mlx.benchmark.MLLMBenchmarkResult · class
vllm_mlx.benchmark.MLLMBenchmarkResult(resolution: str, width: int, height: int, pixels: int, time_seconds: float, tokens_generated: int, tokens_per_second: float, response_preview: str, memory_gb: float = 0.0, mlx_memory_gb: float = 0.0)

Result from a single MLLM benchmark run.

Parameters

Name Type Required Default Description
resolution str yes none Required constructor field.
width int yes none Required constructor field.
height int yes none Required constructor field.
pixels int yes none Required constructor field.
time_seconds float yes none Required constructor field.
tokens_generated int yes none Required constructor field.
tokens_per_second float yes none Required constructor field.
response_preview str yes none Required constructor field.
memory_gb float no 0.0 Optional constructor field; defaults to 0.0.
mlx_memory_gb float no 0.0 Optional constructor field; defaults to 0.0.

Returns

  • Constructs: vllm_mlx.benchmark.MLLMBenchmarkResult

Exceptions and behavior

Class MLLMBenchmarkResult declares 0 direct member(s). No direct raise statement appears in this definition.

View source #L661-L674.

vllm_mlx.benchmark.download_test_image · function
vllm_mlx.benchmark.download_test_image(url: str, timeout: int = 30) -> Image.Image

Download image from URL and return PIL Image.

Parameters

Name Type Required Default Description
url str yes none Required positional or keyword input.
timeout int no 30 Optional positional or keyword input; defaults to 30.

Returns

  • Type: Image.Image
  • Direct return expressions: Image.open(io.BytesIO(response.content))

Exceptions and behavior

Function download_test_image calls requests.get, response.raise_for_status, Image.open, io.BytesIO; returns Image.open(io.BytesIO(response.content)). No direct raise statement appears in this definition.

View source #L677-L684.

vllm_mlx.benchmark.resize_image · function
vllm_mlx.benchmark.resize_image(img: Image.Image, width: int, height: int) -> Image.Image

Resize image to specified dimensions.

Parameters

Name Type Required Default Description
img Image.Image yes none Required positional or keyword input.
width int yes none Required positional or keyword input.
height int yes none Required positional or keyword input.

Returns

  • Type: Image.Image
  • Direct return expressions: img.resize((width, height), Image.Resampling.LANCZOS)

Exceptions and behavior

Function resize_image calls img.resize; returns img.resize((width, height), Image.Resampling.LANCZOS). No direct raise statement appears in this definition.

View source #L687-L689.

vllm_mlx.benchmark.image_to_base64 · function
vllm_mlx.benchmark.image_to_base64(img: Image.Image, format: str = 'JPEG') -> str

Convert PIL Image to base64 data URL.

Parameters

Name Type Required Default Description
img Image.Image yes none Required positional or keyword input.
format str no 'JPEG' Optional positional or keyword input; defaults to 'JPEG'.

Returns

  • Type: str
  • Direct return expressions: f'data:{mime};base64,{b64}'

Exceptions and behavior

Function image_to_base64 calls Image.new, background.paste, img.split, img.convert; returns f'data:{mime};base64,{b64}'. No direct raise statement appears in this definition.

View source #L692-L705.

vllm_mlx.benchmark.benchmark_mllm_resolution · function
vllm_mlx.benchmark.benchmark_mllm_resolution(model, processor, config, base_image: Image.Image, width: int, height: int, max_tokens: int = 256, warmup: bool = False) -> MLLMBenchmarkResult

Run MLLM benchmark for a specific resolution.

Parameters

Name Type Required Default Description
model not annotated yes none Required positional or keyword input.
processor not annotated yes none Required positional or keyword input.
config not annotated yes none Required positional or keyword input.
base_image Image.Image yes none Required positional or keyword input.
width int yes none Required positional or keyword input.
height int yes none Required positional or keyword input.
max_tokens int no 256 Optional positional or keyword input; defaults to 256.
warmup bool no False Optional positional or keyword input; defaults to False.

Returns

  • Type: MLLMBenchmarkResult
  • Direct return expressions: MLLMBenchmarkResult(resolution=resolution_name, width=width, height=height, pixels=pixels, time_seconds=elapsed, tokens…

Exceptions and behavior

Function benchmark_mllm_resolution calls reset_mlx_peak_memory, resize_image, tempfile.NamedTemporaryFile, img.save; returns MLLMBenchmarkResult(resolution=resolution_name, width=width, height=height, pixels=pixels, time_seconds=elapsed, tokens…. No direct raise statement appears in this definition.

View source #L708-L800.

vllm_mlx.benchmark.run_mllm_benchmark · function
vllm_mlx.benchmark.run_mllm_benchmark(model_name: str, quick: bool = False, max_tokens: int = 256, warmup_runs: int = 1) -> list[MLLMBenchmarkResult]

Run MLLM benchmark across multiple image resolutions.

Parameters

Name Type Required Default Description
model_name str yes none HuggingFace model name
quick bool no False If True, test only 4 resolutions
max_tokens int no 256 Max tokens to generate
warmup_runs int no 1 Number of warmup runs

Returns

  • Type: list[MLLMBenchmarkResult]
  • Direct return expressions: []; results

Exceptions and behavior

Function run_mllm_benchmark calls detect_hardware, print, len, tabulate; has 2 explicit return paths. No direct raise statement appears in this definition.

View source #L803-L913.

vllm_mlx.benchmark.print_mllm_summary · function
vllm_mlx.benchmark.print_mllm_summary(results: list[MLLMBenchmarkResult], model_name: str) -> not annotated

Print MLLM benchmark summary.

Parameters

Name Type Required Default Description
results list[MLLMBenchmarkResult] yes none Required positional or keyword input.
model_name str yes none Required positional or keyword input.

Returns

  • Type: not annotated
  • Direct return expressions: None

Exceptions and behavior

Function print_mllm_summary calls print, table_data.append, tabulate, sum; returns None. No direct raise statement appears in this definition.

View source #L916-L975.

vllm_mlx.benchmark.VideoBenchmarkResult · class
vllm_mlx.benchmark.VideoBenchmarkResult(config_name: str, fps: float, max_frames: int, frames_extracted: int, video_duration: float, time_seconds: float, prompt_tokens: int, completion_tokens: int, tokens_per_second: float, response_preview: str, memory_gb: float = 0.0, mlx_memory_gb: float = 0.0)

Result from a single video benchmark run.

Parameters

Name Type Required Default Description
config_name str yes none Required constructor field.
fps float yes none Required constructor field.
max_frames int yes none Required constructor field.
frames_extracted int yes none Required constructor field.
video_duration float yes none Required constructor field.
time_seconds float yes none Required constructor field.
prompt_tokens int yes none Required constructor field.
completion_tokens int yes none Required constructor field.
tokens_per_second float yes none Required constructor field.
response_preview str yes none Required constructor field.
memory_gb float no 0.0 Optional constructor field; defaults to 0.0.
mlx_memory_gb float no 0.0 Optional constructor field; defaults to 0.0.

Returns

  • Constructs: vllm_mlx.benchmark.VideoBenchmarkResult

Exceptions and behavior

Class VideoBenchmarkResult declares 0 direct member(s). No direct raise statement appears in this definition.

View source #L984-L999.

vllm_mlx.benchmark.create_test_video · function
vllm_mlx.benchmark.create_test_video(duration: float = 10.0, fps: float = 30.0, width: int = 640, height: int = 480) -> str

Create a synthetic test video with colored frames and text.

Parameters

Name Type Required Default Description
duration float no 10.0 Optional positional or keyword input; defaults to 10.0.
fps float no 30.0 Optional positional or keyword input; defaults to 30.0.
width int no 640 Optional positional or keyword input; defaults to 640.
height int no 480 Optional positional or keyword input; defaults to 480.

Returns

  • Type: str
  • Direct return expressions: temp_file.name

Exceptions and behavior

Function create_test_video calls tempfile.NamedTemporaryFile, temp_file.close, cv2.VideoWriter_fourcc, cv2.VideoWriter; returns temp_file.name. No direct raise statement appears in this definition.

View source #L1002-L1056.

vllm_mlx.benchmark.download_video · function
vllm_mlx.benchmark.download_video(url: str, timeout: int = 120) -> str

Download video from URL and return local path.

Parameters

Name Type Required Default Description
url str yes none Required positional or keyword input.
timeout int no 120 Optional positional or keyword input; defaults to 120.

Returns

  • Type: str
  • Direct return expressions: temp_file.name

Exceptions and behavior

Function download_video calls print, requests.get, response.raise_for_status, tempfile.NamedTemporaryFile; returns temp_file.name. No direct raise statement appears in this definition.

View source #L1059-L1075.

vllm_mlx.benchmark.get_video_info · function
vllm_mlx.benchmark.get_video_info(video_path: str) -> dict

Get information about a video file.

Parameters

Name Type Required Default Description
video_path str yes none Required positional or keyword input.

Returns

  • Type: dict
  • Direct return expressions: {'error': 'Cannot open video'}; info

Exceptions and behavior

Function get_video_info calls cv2.VideoCapture, cap.isOpened, int, cap.get; has 2 explicit return paths. No direct raise statement appears in this definition.

View source #L1078-L1094.

vllm_mlx.benchmark.benchmark_video_config · function
vllm_mlx.benchmark.benchmark_video_config(model, video_path: str, fps: float, max_frames: int, config_name: str, video_info: dict, max_tokens: int = 150, warmup: bool = False) -> VideoBenchmarkResult

Run a single video benchmark configuration.

Parameters

Name Type Required Default Description
model not annotated yes none Required positional or keyword input.
video_path str yes none Required positional or keyword input.
fps float yes none Required positional or keyword input.
max_frames int yes none Required positional or keyword input.
config_name str yes none Required positional or keyword input.
video_info dict yes none Required positional or keyword input.
max_tokens int no 150 Optional positional or keyword input; defaults to 150.
warmup bool no False Optional positional or keyword input; defaults to False.

Returns

  • Type: VideoBenchmarkResult
  • Direct return expressions: VideoBenchmarkResult(config_name=config_name, fps=fps, max_frames=max_frames, frames_extracted=frames_extracted, video_…

Exceptions and behavior

Function benchmark_video_config calls reset_mlx_peak_memory, print, time.perf_counter, model.generate; returns VideoBenchmarkResult(config_name=config_name, fps=fps, max_frames=max_frames, frames_extracted=frames_extracted, video_…. No direct raise statement appears in this definition.

View source #L1097-L1162.

vllm_mlx.benchmark.run_video_benchmark · function
vllm_mlx.benchmark.run_video_benchmark(model_name: str, video_url: str = None, video_path: str = None, quick: bool = False, max_tokens: int = 150, warmup_runs: int = 1) -> list[VideoBenchmarkResult]

Run video benchmark across multiple frame configurations.

Parameters

Name Type Required Default Description
model_name str yes none HuggingFace MLLM model name
video_url str no None URL to download video from
video_path str no None Local video file path
quick bool no False If True, test only 3 configurations
max_tokens int no 150 Max tokens to generate
warmup_runs int no 1 Number of warmup runs

Returns

  • Type: list[VideoBenchmarkResult]
  • Direct return expressions: results

Exceptions and behavior

Function run_video_benchmark calls detect_hardware, print, len, tabulate; returns results. No direct raise statement appears in this definition.

View source #L1165-L1285.

vllm_mlx.benchmark.print_video_summary · function
vllm_mlx.benchmark.print_video_summary(results: list[VideoBenchmarkResult], model_name: str) -> not annotated

Print video benchmark summary.

Parameters

Name Type Required Default Description
results list[VideoBenchmarkResult] yes none Required positional or keyword input.
model_name str yes none Required positional or keyword input.

Returns

  • Type: not annotated
  • Direct return expressions: None

Exceptions and behavior

Function print_video_summary calls print, sorted, table_data.append, tabulate; returns None. No direct raise statement appears in this definition.

View source #L1288-L1341.

vllm_mlx.benchmark.print_summary · function
vllm_mlx.benchmark.print_summary(summary: BenchmarkSummary) -> not annotated

Print a formatted summary of benchmark results using tabulate.

Parameters

Name Type Required Default Description
summary BenchmarkSummary yes none Required positional or keyword input.

Returns

  • Type: not annotated

Exceptions and behavior

Function print_summary calls print, tabulate, resource_data.append. No direct raise statement appears in this definition.

View source #L1349-L1441.

vllm_mlx.benchmark.main · function
vllm_mlx.benchmark.main() -> not annotated

Run the benchmark.

Parameters

This callable has no explicit inputs.

Returns

  • Type: not annotated

Exceptions and behavior

Function main calls argparse.ArgumentParser, parser.add_argument, parser.parse_args, is_mllm_model. No direct raise statement appears in this definition.

View source #L1444-L1680.

Complete symbol map

This map also includes private definitions and nested helpers. The signature column exposes every explicit input even when an internal helper has no dedicated parameter prose.

Symbol Kind Signature and inputs What it does Source
ResourceMetrics class ResourceMetrics(process_memory_gb: float = 0.0, mlx_cache_gb: float = 0.0, mlx_peak_memory_gb: float = 0.0, system_memory_used_gb: float = 0.0, system_memory_total_gb: float = 0.0) Resource usage metrics during benchmark. #L72-L80
reset_mlx_peak_memory function reset_mlx_peak_memory() -> not annotated Reset MLX peak memory counter. #L83-L95
get_mlx_memory_info function get_mlx_memory_info(reset_peak: bool = True) -> dict Get MLX memory usage information. #L98-L135
get_process_memory function get_process_memory() -> float Get current process memory usage in GB. #L138-L147
get_system_memory function get_system_memory() -> tuple[float, float] Get system memory (used, total) in GB. #L150-L159
ResourceMonitor class ResourceMonitor() Monitor system resources during benchmark runs. #L162-L213
ResourceMonitor.__init__ method ResourceMonitor.__init__() -> not annotated Method ResourceMonitor.__init__ updates self.samples, self._start_time, self._start_memory. #L165-L168
ResourceMonitor.start method ResourceMonitor.start() -> not annotated Start monitoring. #L170-L176
ResourceMonitor.sample method ResourceMonitor.sample() -> ResourceMetrics Take a resource sample. #L178-L192
ResourceMonitor.get_summary method ResourceMonitor.get_summary() -> ResourceMetrics Get summary of all samples. #L194-L213
BenchmarkResult class BenchmarkResult(prompt: str, prompt_tokens: int, generated_tokens: int, ttft: float, total_time: float, tpot: float = 0.0, generation_tps: float = 0.0, processing_tps: float = 0.0) Results from a single benchmark run. #L235-L268
BenchmarkResult.__post_init__ method BenchmarkResult.__post_init__() -> not annotated Method BenchmarkResult.__post_init__ updates self.tpot, self.generation_tps, self.processing_tps. #L251-L268
BenchmarkSummary class BenchmarkSummary(model_name: str, num_runs: int, total_prompt_tokens: int, total_generated_tokens: int, total_time: float, ttft_mean: float, ttft_min: float, ttft_max: float, ttft_p50: float, ttft_p95: float, tpot_mean: float, tpot_min: float, tpot_max: float, generation_tps_mean: float, generation_tps_max: float, processing_tps_mean: float, latency_mean: float, latency_min: float, latency_max: float, latency_p50: float, latency_p95: float, total_throughput_tps: float, requests_per_second: float, hardware_chip: str = '', hardware_memory_gb: float = 0.0, hardware_bandwidth_gbs: float = 0.0, resources: ResourceMetrics = field(default_factory=ResourceMetrics)) Summary statistics across all benchmark runs. #L272-L315
calculate_percentile function calculate_percentile(data: list, percentile: float) -> float Calculate percentile from a list. #L318-L325
benchmark_single_prompt function benchmark_single_prompt(model, tokenizer, prompt: str, max_tokens: int = 256, temperature: float = 0.7) -> Optional[BenchmarkResult] Benchmark a single prompt with detailed timing. #L328-L394
run_benchmark function run_benchmark(model_name: str, num_prompts: int = 5, max_tokens: int = 256, temperature: float = 0.7, warmup_runs: int = 1) -> Optional[BenchmarkSummary] Run the full benchmark suite. #L397-L610
is_mllm_model function is_mllm_model(model_name: str) -> bool Check if model name indicates a multimodal language model. #L651-L657
MLLMBenchmarkResult class MLLMBenchmarkResult(resolution: str, width: int, height: int, pixels: int, time_seconds: float, tokens_generated: int, tokens_per_second: float, response_preview: str, memory_gb: float = 0.0, mlx_memory_gb: float = 0.0) Result from a single MLLM benchmark run. #L661-L674
download_test_image function download_test_image(url: str, timeout: int = 30) -> Image.Image Download image from URL and return PIL Image. #L677-L684
resize_image function resize_image(img: Image.Image, width: int, height: int) -> Image.Image Resize image to specified dimensions. #L687-L689
image_to_base64 function image_to_base64(img: Image.Image, format: str = 'JPEG') -> str Convert PIL Image to base64 data URL. #L692-L705
benchmark_mllm_resolution function benchmark_mllm_resolution(model, processor, config, base_image: Image.Image, width: int, height: int, max_tokens: int = 256, warmup: bool = False) -> MLLMBenchmarkResult Run MLLM benchmark for a specific resolution. #L708-L800
run_mllm_benchmark function run_mllm_benchmark(model_name: str, quick: bool = False, max_tokens: int = 256, warmup_runs: int = 1) -> list[MLLMBenchmarkResult] Run MLLM benchmark across multiple image resolutions. #L803-L913
print_mllm_summary function print_mllm_summary(results: list[MLLMBenchmarkResult], model_name: str) -> not annotated Print MLLM benchmark summary. #L916-L975
VideoBenchmarkResult class VideoBenchmarkResult(config_name: str, fps: float, max_frames: int, frames_extracted: int, video_duration: float, time_seconds: float, prompt_tokens: int, completion_tokens: int, tokens_per_second: float, response_preview: str, memory_gb: float = 0.0, mlx_memory_gb: float = 0.0) Result from a single video benchmark run. #L984-L999
create_test_video function create_test_video(duration: float = 10.0, fps: float = 30.0, width: int = 640, height: int = 480) -> str Create a synthetic test video with colored frames and text. #L1002-L1056
download_video function download_video(url: str, timeout: int = 120) -> str Download video from URL and return local path. #L1059-L1075
get_video_info function get_video_info(video_path: str) -> dict Get information about a video file. #L1078-L1094
benchmark_video_config function benchmark_video_config(model, video_path: str, fps: float, max_frames: int, config_name: str, video_info: dict, max_tokens: int = 150, warmup: bool = False) -> VideoBenchmarkResult Run a single video benchmark configuration. #L1097-L1162
run_video_benchmark function run_video_benchmark(model_name: str, video_url: str = None, video_path: str = None, quick: bool = False, max_tokens: int = 150, warmup_runs: int = 1) -> list[VideoBenchmarkResult] Run video benchmark across multiple frame configurations. #L1165-L1285
print_video_summary function print_video_summary(results: list[VideoBenchmarkResult], model_name: str) -> not annotated Print video benchmark summary. #L1288-L1341
print_summary function print_summary(summary: BenchmarkSummary) -> not annotated Print a formatted summary of benchmark results using tabulate. #L1349-L1441
main function main() -> not annotated Run the benchmark. #L1444-L1680