Artificial Intelligence in Finance

How To Build Your Own LLM Runtime From Scratch

The development of a custom runtime is often viewed as a redundant exercise given the maturity of existing open-source frameworks. Yet, for engineers and researchers, the ability to "own" every barrier and capture every CUDA graph offers a level of optimization and customization that black-box solutions cannot provide. By stripping away layers of abstraction, the annotated-llm-runtime reveals the intricate mechanics of Tensor Memory Accelerator (TMA) usage, warp specialization, and memory-mapped binary formats, offering a blueprint for future high-efficiency inference engines.

Technical Architecture and Model Specifications

The runtime is designed to facilitate the execution of Qwen2.5-Coder-7B, a model that utilizes the Transformer architecture with several modern enhancements. The Qwen2.5-Coder-7B-Instruct variant features 28 decoder layers, a hidden size of 3,584, and an MLP (Multi-Layer Perceptron) intermediate size of 18,944. Its vocabulary size is extensive, totaling 152,064 tokens.

A defining characteristic of this implementation is its use of Grouped-Query Attention (GQA). In this configuration, 28 query heads share 4 Key-Value (KV) heads, resulting in a 7:1 ratio. This optimization significantly reduces the KV cache footprint, which is vital for maintaining high throughput during the decoding phase. On the hardware level, the runtime pages the KV cache at 16 tokens per page in FP16 precision. This aligns perfectly with the 128-byte L2 cache lines of the NVIDIA Hopper architecture, ensuring that each physical page resides at a clean 16 KiB boundary, minimizing memory bank conflicts and maximizing bandwidth utilization.

The quantization strategy employed is symmetric group-wise INT4 with a group size of 128. While weights are compressed to 4-bit integers to save memory and increase throughput, the activations remain in FP16 or FP32. This "hybrid" approach ensures that numerical stability is maintained while benefiting from the reduced memory pressure of quantized weights.

Performance Benchmarking and Comparative Analysis

To assess the efficacy of the custom runtime, it was benchmarked against the industry standard, llama.cpp, using an NVIDIA H100 GPU. The protocol involved a prompt of 512 tokens and the generation of 128 tokens using a greedy decoding strategy.

How To Build Your Own LLM Runtime From Scratch
Metric Annotated LLM Runtime llama.cpp (Q4_K_M)
Time to First Token (TTFT) 128 ms 43 ms
Decode Inter-Token Latency (ITL) 16.7 ms/token 4.95 ms/token
Decode Throughput 60 tokens/s 200 tokens/s

While the custom runtime currently trails llama.cpp in raw throughput, the project’s primary objective is not immediate displacement but rather the demonstration of architectural principles. The data reveals that the single most significant performance lever was the transition from eager kernel execution to CUDA graph-based execution. Eager per-token decoding originally clocked in at 119 ms per token; by capturing the steady-state decode in a CUDA graph, latency was reduced to approximately 17 ms per token—a 7x improvement achieved without changing the underlying mathematical kernels.

Chronology of Development and Technical Hurdles

The development of the annotated-llm-runtime followed a rigorous phase-based approach, moving from basic arithmetic verification to complex hardware synchronization.

Phase 1: The Weight Serialization Protocol

The team established a custom binary format dubbed .nanoqwen. This format utilizes a memory-mapped (mmap) approach, allowing the runtime to access weights directly without the overhead of YAML or JSON parsing on the hot path. A strict 256-byte header ensures file integrity, including a "magic string" (NANOQWEN) that must be validated before the GPU allocates VRAM.

Phase 2: Synchronization and Warp Specialization

The implementation of the paged attention kernel introduced significant complexity. To maximize the H100’s capabilities, the developer employed a warp-specialized design. In this model, one "producer" warp issues bulk TMA copies to move data from Global Memory (HBM) to Shared Memory (SMEM), while six "consumer" warps perform the softmax and weighted-V accumulation.

A critical bug was identified during this phase involving the __syncthreads() function. In an early iteration, the barrier was placed inside a conditional branch reserved for the producer warp. Because __syncthreads() is a block-wide barrier, the consumer warps skipped it, leading to a race condition where they read data before the TMA transfer was complete. Correcting this required a move to mbarriers—Hopper-specific hardware objects that provide transaction-aware synchronization.

Phase 3: The Integration of CUDA Graphs

Recognizing that host-side overhead was the primary bottleneck, the development shifted toward CUDA graphs. Because the decoding process involves hundreds of kernel launches per token, the round-trip time between the CPU and GPU driver became prohibitive. By capturing these launches into a static graph, the runtime bypassed the driver overhead. To handle the logic of page boundaries, the system pre-captures two versions of the graph—one for standard steps and one for steps that cross a KV page boundary—dynamically switching between them at runtime.

How To Build Your Own LLM Runtime From Scratch

Phase 4: Arithmetic Optimization (Path Selection)

The final phase involved choosing between two methods for INT4 weight-multiplication. Path A utilized __dp4a (INT8 dot product), which required an extra step to quantize activations. Path B utilized prmt.b32 (byte permute) to unpack INT4 weights into FP16 for direct multiplication. Surprisingly, benchmarking on the Hopper architecture showed that Path B outperformed Path A, despite the theoretical bandwidth advantages of INT8 activations. This led to the adoption of the "ValueShuffle" layout, which optimizes nibble placement for the Hopper permute pipes.

Analysis of Broader Industry Implications

The release of the annotated-llm-runtime comes at a time when the "software-hardware co-design" philosophy is becoming paramount. As AI models scale, the overhead of general-purpose runtimes becomes a financial and operational burden. This project demonstrates that even a small, highly specialized codebase can achieve functional parity with massive frameworks, provided the developer has a deep understanding of the underlying silicon.

Industry analysts suggest that this trend toward bespoke runtimes will likely accelerate in three specific areas:

  1. Edge and Embedded AI: Where memory and power constraints require the removal of every unnecessary software abstraction.
  2. Proprietary Enterprise Clusters: Where companies operating thousands of GPUs can save millions in energy and compute costs by squeezing a 5-10% efficiency gain from custom kernels.
  3. Educational and Research Foundations: Providing a "transparent box" for the next generation of GPU engineers to study.

The decision to avoid locking GPU clocks during benchmarking also reflects a shift toward more "honest" performance reporting. By allowing the H100 to operate under standard thermal and power management, the benchmarks provide a realistic expectation of performance in production environments rather than idealized laboratory settings.

Conclusion and Future Outlook

The annotated-llm-runtime project successfully demonstrates that a functional, high-performance LLM decoder can be built with approximately two dozen source files. While it currently serves as a learning tool and a reference implementation, it highlights the technical maturity required to leverage NVIDIA’s Hopper architecture.

The project concludes with several key takeaways for the AI engineering community: the necessity of CUDA graphs for low-latency decoding, the superiority of hardware-specific synchronization objects over generic barriers, and the fact that memory bandwidth remains the ultimate arbiter of performance, regardless of theoretical compute TFLOPS. As Qwen2.5-Coder-7B and similar models continue to evolve, the ability to modify the underlying runtime will remain a significant competitive advantage for developers seeking to push the boundaries of what is possible in real-time AI inference.

Related Articles

Leave a Reply

Your email address will not be published. Required fields are marked *

Back to top button