Back to Feed
Efficiency & Inference

Running Large AI Models on Consumer Hardware

Original: FreeToken: Efficient Edge-Native MoE Serving with Bandwidth-Adaptive Execution

Listen to the summary

Uses a voice available on your device

Audio options
On this page 5 sections
Related concepts 4 concepts

Key Takeaways

  • FreeToken allows consumer-grade hardware like the RTX 4060 and 5090 to serve high-parameter models previously limited to datacenter-class clusters.
  • The system achieves 77 to 83 tokens per second on Qwen3.6-35B-A3B and 39.3 tokens per second on a 35B model using an 8GB RTX 4060 laptop.
  • A bandwidth-adaptive execution policy dynamically shifts expert loading between PCIe transfer and direct CPU processing to handle memory constraints.
  • Expert double buffering and semantic-aware state caching optimize latency by overlapping computation with data transfer and enabling prefix reuse.

Summary & Methodology Analysis

FreeToken addresses the gap in deploying Mixture of Experts (MoE) models, which utilize a specific architecture that activates only a subset of parameters per token, on consumer hardware. To manage the high demand for memory and bandwidth, it employs full-layer expert double buffering. This technique hides latency by streaming the next layer of experts over the PCIe bus while the GPU computes the current layer. Additionally, the system uses semantic-aware state caching, which pins recurrent-state checkpoints at specific boundaries like tool calls or thinking segments, allowing for partial reuse when context is modified. For long-term residency, a shared LRU expert cache maintains active experts based on temporal routing locality, resizing according to current memory availability.

Interactive System Flowchart

Click diagram to expand and zoom

Illustrative Implementation

A short sketch of the paper's core idea, not the authors' own code.

# Illustrative sketch (not from the paper)
import torch
from collections import OrderedDict

# Double‑buffer for two consecutive expert layers
class DoubleBuffer:
    def __init__(self, layer_fn):
        self.current = None          # GPU resident experts for current layer
        self.next = None             # Prefetched experts for next layer
        self.layer_fn = layer_fn

    def load_next(self, expert_ids):
        # Simulate async PCIe transfer (placeholder)
        self.next = torch.nn.ModuleList([self.layer_fn(eid) for eid in expert_ids])

    def swap(self):
        self.current, self.next = self.next, None

# Simple LRU cache for experts on GPU
class ExpertLRUCache:
    def __init__(self, capacity):
        self.capacity = capacity
        self.cache = OrderedDict()

    def get(self, eid):
        if eid in self.cache:
            self.cache.move_to_end(eid)
            return self.cache[eid]
        return None

    def put(self, eid, expert):
        self.cache[eid] = expert
        self.cache.move_to_end(eid)
        if len(self.cache) > self.capacity:
            self.cache.popitem(last=False)  # evict LRU

# Bandwidth‑adaptive execution (q* policy)
def execute_token(token, cache, bandwidth_pcie, bandwidth_cpu):
    # Decide where to fetch missing expert
    if bandwidth_pcie >= bandwidth_cpu:
        # Prefer PCIe fill then GPU exec
        expert = cache.get(token.expert_id) or load_expert_via_pcie(token.expert_id)
    else:
        # Direct CPU execution fallback
        expert = load_expert_via_cpu(token.expert_id)
    # Run expert (placeholder)
    return expert(token.input)

# Placeholder loaders
def load_expert_via_pcie(eid):
    # In real system this streams over PCIe into GPU memory
    return torch.nn.Linear(1024, 1024)

def load_expert_via_cpu(eid):
    # CPU‑only execution path
    return lambda x: x  # no‑op for illustration

# Example workflow for a single decode step
def decode_step(tokens, double_buf, lru_cache, bw_pcie, bw_cpu):
    # Prefetch next layer experts while current layer runs
    double_buf.load_next([t.expert_id for t in tokens])
    outputs = []
    for token in tokens:
        expert = lru_cache.get(token.expert_id)
        if expert is None:
            expert = execute_token(token, lru_cache, bw_pcie, bw_cpu)
            lru_cache.put(token.expert_id, expert)
        outputs.append(expert(token.input))
    double_buf.swap()  # hide latency for next layer
    return outputs

Cross-Examination & FAQs

A deeper dive clarifying mechanics, constraints, and baseline evaluations.

Q1. What is the primary problem FreeToken solves?

It addresses the accessibility gap for users who want to run large Mixture of Experts models but lack expensive datacenter-grade GPU clusters.

Q2. Can I run this on consumer hardware?

Yes, it is designed for consumer hardware and has been tested on platforms like an 8GB RTX 4060 laptop and an RTX 5090.

Q3. Does this system work for all model sizes?

It is optimized for large models like Qwen3.6-35B-A3B and DeepSeek-V4-Flash, though effectiveness depends on available hardware capacity.

Q4. What happens if my GPU memory is limited?

If the GPU memory cannot accommodate two full-layer buffers, the system reverts to on-demand loading of experts.

Q5. How does the q* policy manage bandwidth bottlenecks?

The bandwidth-adaptive execution policy partitions decode-time cache misses by choosing between PCIe-based cache fills and direct CPU-based execution based on real-time bandwidth measurements.

Q6. What is the role of the shared LRU expert cache?

It manages which experts stay resident on the GPU based on how often they are used, adjusting its size dynamically to fit the current memory budget.

Q7. Are there scenarios where the system performs poorly?

On platforms where a fast pinned DMA path cannot be established, the system falls back to a slower pure-CPU backend.

Q8. Which specific models were used in testing?

Testing included Kimi-K3, GLM-5.2, DeepSeek-V4-Flash-0731, and Qwen3.6-35B-A3B.

Q9. Does this paper compare against other serving frameworks?

The paper references systems like llama.cpp, KTransformers, Ollama, and MoE-Infinity, though it focuses on its own architectural contributions.

Flag an issue

What is wrong with this summary?

What is wrong?