Skip to content

feat(optimization): layer-by-layer inference mode for batch/offline processing #1946

Description

@mrveiss

Summary

Add a "memory-constrained" inference mode that uses airllm's layer-by-layer technique to run models exceeding available VRAM, targeting non-interactive batch workloads like knowledge base processing and research workflows.

Background

airllm enables running 70B–405B parameter models on as little as 4GB VRAM by loading one transformer layer at a time from disk, processing it, then evicting it. The tradeoff is speed — inference takes 30–120 seconds per response for 70B models.

This is not suitable for interactive chat but is viable for:

Currently AutoBot's largest local model is 13B. Layer-by-layer inference would allow running 70B+ models on the RTX 4070 (8GB VRAM) for tasks where the quality improvement justifies the latency cost.

Implementation

Approach A: Integrate airllm as a Provider

# New provider: llm_providers/airllm_provider.py
from airllm import AutoModel

class AirLLMProvider:
    def __init__(self, model_name: str):
        self.model = AutoModel.from_pretrained(
            model_name,
            compression="4bit",  # block-wise quantization
            profiling_mode=True,
        )
    
    async def generate(self, prompt: str, **kwargs) -> str:
        # Layer-by-layer inference — slow but fits in VRAM
        ...

Approach B: Implement the Pattern Natively

Implement the core technique (model splitting + sequential layer loading) in the NPU inference server as an alternative backend mode, without depending on airllm directly.

Prerequisites

  1. Model splitting pipeline: one-time preprocessing to split models into per-layer safetensors files
  2. Prefetch infrastructure (see related NPU prefetch issue)
  3. KV cache management across sequential layer passes

Key Files

  • autobot-backend/llm_interface_pkg/providers/ — new provider or mode
  • autobot-infrastructure/shared/scripts/ai-ml/optimize_llm_models.py — model splitting step
  • autobot-backend/llm_interface_pkg/optimization/router.py — routing to memory-constrained mode

Acceptance Criteria

  • Layer-by-layer inference mode implemented (Approach A or B)
  • Model splitting pipeline for one-time preprocessing
  • Integration with OptimizationRouter — auto-selects when model exceeds VRAM
  • Block-wise 4-bit quantization applied to layer files for faster loading
  • Prefetch next layer while current executes
  • Works for batch/offline tasks (not exposed to interactive chat by default)
  • Benchmarks: latency per token, memory usage, accuracy vs full-precision

Effort

High effort, medium impact (enables new capabilities but limited to batch use cases).

Activity

  1. mrveiss commented on Mar 20, 2026

    @mrveiss
    OwnerAuthor

    Additional Techniques from Deeper airllm Analysis

    1. Model Sharding with Crash-Safe Done Markers

    The split-and-save pipeline should use .safetensors.done marker files for crash safety — if splitting is interrupted, only incomplete layers are reprocessed on retry. Also includes disk space pre-checking via check_space() before splitting begins.

    2. Buffers-Only GPU Initialization

    When creating the empty-weight model scaffold, only model buffers (non-trainable tensors like LayerNorm stats, attention masks — a few KB total) should be moved to GPU. All weight parameters stay on meta device until loaded per-layer.

    for buffer_name, buffer in model.named_buffers():
        set_module_tensor_to_device(model, buffer_name, 'cuda',
                                    value=buffer, dtype=running_dtype)

    Missing this distinction causes either errors (if buffers aren't on GPU) or wasted memory (if all params are on GPU).

    3. Lazy Shard Downloading

    Download individual model shards from HuggingFace on-demand during splitting rather than all at once. Combined with delete_original=True, peak disk usage = (1 shard + all split layers so far) instead of (entire model + all split layers).

    4. Aggressive Model Reboot (Optional)

    airllm deletes and recreates the empty model scaffold at the start of every forward pass (del self.model; clean_memory(); self.init_model()) to guarantee no stale weights in GPU memory. AutoBot could adopt a softer version: rebuild every N inference calls as a memory leak safety net.

    These should all be incorporated into the layer-by-layer inference implementation.

  2. added and removed
    enhancementNew feature or request
    on Mar 27, 2026
  3. mrveiss commented on Mar 31, 2026

    @mrveiss
    OwnerAuthor

    Merged in PR #3089. Layer-by-layer inference for batch processing on memory-constrained GPUs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions