{
  "@context": "https://schema.org",
  "@id": "https://aggr.aymericbeaumet.com/items/zml-ai/2026-03-24-introducing-zml-v2/#webpage",
  "@type": [
    "WebPage",
    "ArchiveComponent"
  ],
  "articleBody": "ZML is an inference stack built close to the hardware. It lowers models directly onto NVIDIA, AMD, TPU, and Trainium targets from a single codebase, without depending on and suffering from the Python-heavy runtime layers that most of the ecosystem is built around.\n\nThe guiding idea behind zml/v1 was simplicity: give ZML a model and its weights, and the system would take care of compilation, placement, and execution for you. That made the first version approachable and effective for standard deployments, but it also baked too much behavior into implicit global state. As the project pushed into partial compilation, custom passes, sharding, quantization, and more backend-specific execution paths, those implicit shortcuts became constraints. ZML/v2 is the rewrite that makes those concepts explicit: platform ownership, compilation, memory, IO, and placement are now first-class, so advanced use cases can be expressed directly instead of forced through workarounds.\n\n## Composability as a core principle\n\nZML/v2 is a complete rewrite of the framework with a focus on developer experience, performance and most importantly **composability**. This is a fundamental departure from the original design which was a lot more turnkey but could make more complex programs a bit harder than necessary.\n\nSo we’ve decided to strongly orient the design towards composability while also offering an uplift in performance.\n\n## Explicit over implicit\n\nThe new API centers around `zml.Platform`s, which is the main abstraction across accelerators, runtimes, IO etc. In ZML, a platform is instantiated and from then on used to transfer data, build, compile and execute programs.\n\nThis is how it all starts:\n\n```zig\nconst platform: *zml.Platform = try .auto(allocator, io, .{});\n```\n\nZML offers various platforms selection mechanisms: compile-time, runtime and manual. The automatic runtime selection is the default and will pick the best available platform on the system, but users can also choose to compile for a specific platform or manually create a platform with custom options.\n\nThe then built program can now run transparently on all comptime-time enabled platforms, which can be enabled via the `--@zml//platforms:{cuda,rocm,tpu,neuron}=true` build flags. Doing so will download the runtime, strip it to its bare minimum and embed it inside the binary sandbox.\n\nFor instance, here is the **entire** CUDA sandbox:\n\n```\n$ tree --du -h bazel-bin/examples/llm/llm.runfiles/+cuda_packages+libpjrt_cuda/sandbox/\n[2.9G]  bazel-bin/examples/llm/llm.runfiles/+cuda_packages+libpjrt_cuda/sandbox/\n├── [ 82M]  bin\n│   ├── [3.0M]  compat_probe\n│   ├── [ 40M]  nvlink\n│   └── [ 39M]  ptxas\n├── [2.8G]  lib\n│   ├── [409M]  compat\n│   │   ├── [ 11M]  libcudadebugger.so.1\n│   │   ├── [ 94M]  libcuda.so.1\n│   │   ├── [ 86M]  libnvidia-gpucomp.so.590.48.01\n│   │   ├── [ 24M]  libnvidia-nvvm70.so.4\n│   │   ├── [ 75M]  libnvidia-nvvm.so.4\n│   │   ├── [ 14K]  libnvidia-pkcs11-openssl3.so.590.48.01\n│   │   ├── [ 31M]  libnvidia-ptxjitcompiler.so.1\n│   │   └── [ 90M]  libnvidia-tileiras.so.590.48.01\n│   ├── [479M]  libcublasLt.so.13\n│   ├── [ 52M]  libcublas.so.13\n│   ├── [740K]  libcudart.so.13\n│   ├── [104M]  libcudnn_adv.so.9\n│   ├── [2.3M]  libcudnn_cnn.so.9\n│   ├── [233M]  libcudnn_engines_precompiled.so.9\n│   ├── [ 26M]  libcudnn_engines_runtime_compiled.so.9\n│   ├── [3.5M]  libcudnn_graph.so.9\n│   ├── [ 56M]  libcudnn_heuristic.so.9\n│   ├── [ 37M]  libcudnn_ops.so.9\n│   ├── [126K]  libcudnn.so.9\n│   ├── [286M]  libcufft.so.12\n│   ├── [4.4M]  libcupti.so.13\n│   ├── [136M]  libcusolver.so.12\n│   ├── [162M]  libcusparse.so.12\n│   ├── [218M]  libnccl.so.2\n│   ├── [ 95M]  libnvJitLink.so.13\n│   ├── [4.2M]  libnvrtc-builtins.so.13.1\n│   ├── [109M]  libnvrtc.so.13\n│   ├── [ 40M]  libnvshmem_host.so.3\n│   ├── [ 39K]  libnvtx3interop.so\n│   ├── [383M]  libpjrt_cuda.so\n│   ├── [2.9M]  libzmlxcuda.so.0\n│   ├── [118K]  libz.so.1\n│   ├── [ 72K]  nvshmem_bootstrap_uid.so.3\n│   └── [1023K]  nvshmem_transport_ibrc.so.4\n└── [ 77M]  nvvm\n    ├── [ 77M]  bin\n    │   └── [ 77M]  cicc\n    └── [458K]  libdevice\n        └── [454K]  libdevice.10.bc\n```\n\n## Pinned Memory Allocators\n\nZML/v2 enables the explicit allocation and use of pinned memory. Pinned memory is memory that is not movable nor swappable and thus can be directly accessed by the DMA engine of the accelerators. This functionality is exposed via the `zml.mem.DmaAllocator` which, combined with Zig’s explicit allocator model, enables unique optimizations and removes extraneous copies found in other frameworks.\n\n## Zero and overlapped copy primitives\n\nData transfers between host and accelerator now compose with `std.Io.Writer` via `zml.io.MemoryWriter`, enabling zero-copy and overlapped data movement across the board.\n\nFor instance, loading a model from disk to GPU memory now happens at SSD speed when using `O_DIRECT`, even with staging through the system memory, since transfers are overlapped. This enables NVIDIA GPUDirect-like performance on raw POSIX.\n\n```\n$ bazel build --config=release //examples/llm --@zml//platforms:cuda=true\n$ bazel-bin/examples/llm/llm --model=/var/models/meta-llama/Llama-3.1-8B-Instruct/\n...\ninfo(llm): Selected backend: .cuda_fa2\ninfo(llm): Loaded tokenizer [181.256ms]\ninfo(llama): Loaded weights [14.96GiB, 1.165s, 12.83GiB/s]\n```\n\n## Userland Virtual File System\n\nThanks to injectable `std.Io`, ZML implements a full userland VFS built into the program. It supports local files, HTTP endpoints, S3 buckets and Hugging Face repositories. Concretely, this means that models can be loaded directly from each of those sources without downloading to disk first, regardless of the underlying FS implementation.\n\nLet’s try to register an HF implementation and load the tokenizer directly from Hugging Face:\n\n```zig\nvar vfs: zml.io.VFS = try .init(init.gpa, init.io);\ndefer vfs.deinit();\n\nvar hf_vfs: zml.io.VFS.HF = try .auto(init.gpa, init.io, &http_client, init.environ_map);\ndefer hf_vfs.deinit();\ntry vfs.register(\"hf\", hf_vfs.io());\n\n// Use the VFS IO from now on\nconst io = vfs.io();\n\nconst tokenizer: zml.Tokenizer = blk: {\n    const file = try std.Io.Dir.openFile(.cwd(), io, \"hf://Qwen/Qwen3-8B/tokenizer.json\", .{});\n    defer file.close(io);\n    var reader = file.reader(init.gpa, &.{});\n    const bytes = try reader.interface.readAlloc(init.gpa, try file.length(io));\n    defer init.gpa.free(bytes);\n    break :blk try .fromBytes(init.gpa, io, bytes);\n};\n```\n\nOr load the model directly from Hugging Face:\n\n```\n$ bazel-bin/examples/llm/llm --model=hf://meta-llama/Llama-3.1-8B-Instruct\n```\n\n## Powerful sharding primitives\n\nSharding is now a first-class citizen of the programming model instead of an implicit backend detail. We introduce a new public `zml.sharding` API with `PhysicalMesh`, `LogicalMesh`, `Strategy`, `Sharding`, and `Placement`. Compile / load / buffer APIs now take explicit sharding information and finally `zml.ops.manualComputation` expresses a shard-local primitive similar to JAX’s `shard_map`.\n\nIt also fully leverages [Shardy](https://openxla.org/shardy) or [GSPMD](https://research.google/blog/general-and-scalable-parallelization-for-neural-networks/) based on the target platform transparently.\n\n## Pluggable Attention backend\n\nZML/v2 provides a pluggable attention backend system, giving a clean way to select and configure different attention implementations without rewriting model code around each kernel.\n\nInstead of baking backend-specific logic into every call site, `zml.attention` exposes an explicit `Backend` plus backend-typed `Parameters`, `Metadata`, and paged-attention `Context`, so the same high-level attention path can target vanilla behavior or optimized CUDA FlashAttention variants like Tri-Dao’s FA2 and FA3.\n\nThe backend is selected automatically based on the platform and accelerator.\n\nIn this release, we took the opportunity to integrate [FlashAttention 2 and 3 built on CUDA for `sm80` up to `sm121`](https://github.com/zml/flash-attention/releases/tag/v2026.3.23).\n\n## Complete build sandboxing\n\nOur build now runs entirely on the 100% hermetic LLVM toolchain [@llvm](https://github.com/cerisier/toolchains_llvm_bootstrapped). This enables full reproducibility, better cross-compilation support, and a more consistent development experience across platforms. This means that ZML supports remote execution on services such as [BuildBuddy](https://www.buildbuddy.io/) or [NativeLink](https://www.nativelink.com/).\n\nOn macOS, we no longer rely on Xcode nor Command Line Tools to build ZML. The macOS SDK is downloaded as part of the build.\n\nCross compilation is also fully supported, enabling fully working containers for any supported ZML platform to be built right from a Mac.\n\n## //examples/llm\n\nTry it today via the `llm` CLI:\n\n```\n$ bazel build --config=release //examples/llm --@zml//platforms:cuda=true\n$ bazel-bin/examples/llm/llm --model=hf://Qwen/Qwen3.5-9B\n```\n",
  "authors": [],
  "captured_at": "2026-09-08T10:17:10.166315+00:00",
  "category": "ai",
  "content_html": "<p>ZML is an inference stack built close to the hardware. It lowers models directly onto NVIDIA, AMD, TPU, and Trainium targets from a single codebase, without depending on and suffering from the Python-heavy runtime layers that most of the ecosystem is built around.</p>\n<p>The guiding idea behind zml/v1 was simplicity: give ZML a model and its weights, and the system would take care of compilation, placement, and execution for you. That made the first version approachable and effective for standard deployments, but it also baked too much behavior into implicit global state. As the project pushed into partial compilation, custom passes, sharding, quantization, and more backend-specific execution paths, those implicit shortcuts became constraints. ZML/v2 is the rewrite that makes those concepts explicit: platform ownership, compilation, memory, IO, and placement are now first-class, so advanced use cases can be expressed directly instead of forced through workarounds.</p>\n<h2>Composability as a core principle</h2>\n<p>ZML/v2 is a complete rewrite of the framework with a focus on developer experience, performance and most importantly <strong>composability</strong>. This is a fundamental departure from the original design which was a lot more turnkey but could make more complex programs a bit harder than necessary.</p>\n<p>So we’ve decided to strongly orient the design towards composability while also offering an uplift in performance.</p>\n<h2>Explicit over implicit</h2>\n<p>The new API centers around <code>zml.Platform</code>s, which is the main abstraction across accelerators, runtimes, IO etc. In ZML, a platform is instantiated and from then on used to transfer data, build, compile and execute programs.</p>\n<p>This is how it all starts:</p>\n<pre><code class=\"language-zig\"><span class=\"code-snippet\" data-language=\"Zig\">const platform: *zml.Platform = try .auto(allocator, io, .{});\n</span></code></pre>\n<p>ZML offers various platforms selection mechanisms: compile-time, runtime and manual. The automatic runtime selection is the default and will pick the best available platform on the system, but users can also choose to compile for a specific platform or manually create a platform with custom options.</p>\n<p>The then built program can now run transparently on all comptime-time enabled platforms, which can be enabled via the <code>--@zml//platforms:{cuda,rocm,tpu,neuron}=true</code> build flags. Doing so will download the runtime, strip it to its bare minimum and embed it inside the binary sandbox.</p>\n<p>For instance, here is the <strong>entire</strong> CUDA sandbox:</p>\n<pre><code><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">$</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> tree<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>du</span><span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> -</span>h</span> bazel-bin/examples/llm/llm.runfiles/+cuda_packages+libpjrt_cuda/sandbox/</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">[2.9G]</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">  bazel-bin/examples/llm/llm.runfiles/+cuda_packages+libpjrt_cuda/sandbox/</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">├──</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 82M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  bin</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>3.0M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  compat_probe</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 40M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  nvlink</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   └── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 39M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  ptxas</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">├──</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>2.8G<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  lib</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>409M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  compat</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   │   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 11M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libcudadebugger.so.1</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   │   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 94M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libcuda.so.1</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   │   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 86M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libnvidia-gpucomp.so.590.48.01</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   │   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 24M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libnvidia-nvvm70.so.4</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   │   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 75M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libnvidia-nvvm.so.4</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   │   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 14K<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libnvidia-pkcs11-openssl3.so.590.48.01</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   │   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 31M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libnvidia-ptxjitcompiler.so.1</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   │   └── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 90M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libnvidia-tileiras.so.590.48.01</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>479M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libcublasLt.so.13</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 52M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libcublas.so.13</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>740K<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libcudart.so.13</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>104M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libcudnn_adv.so.9</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>2.3M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libcudnn_cnn.so.9</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>233M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libcudnn_engines_precompiled.so.9</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 26M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libcudnn_engines_runtime_compiled.so.9</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>3.5M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libcudnn_graph.so.9</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 56M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libcudnn_heuristic.so.9</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 37M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libcudnn_ops.so.9</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>126K<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libcudnn.so.9</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>286M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libcufft.so.12</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>4.4M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libcupti.so.13</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>136M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libcusolver.so.12</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>162M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libcusparse.so.12</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>218M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libnccl.so.2</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 95M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libnvJitLink.so.13</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>4.2M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libnvrtc-builtins.so.13.1</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>109M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libnvrtc.so.13</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 40M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libnvshmem_host.so.3</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 39K<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libnvtx3interop.so</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>383M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libpjrt_cuda.so</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>2.9M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libzmlxcuda.so.0</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>118K<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libz.so.1</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   ├── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 72K<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  nvshmem_bootstrap_uid.so.3</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   └── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>1023K<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  nvshmem_transport_ibrc.so.4</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">└──</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 77M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  nvvm</span>\n    <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">├──</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 77M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  bin</span>\n    <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">│</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">   └── <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span> 77M<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  cicc</span>\n    <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">└──</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>458K<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libdevice</span>\n        <span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">└──</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>454K<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span>  libdevice.10.bc</span>\n</span></span></code></pre>\n<h2>Pinned Memory Allocators</h2>\n<p>ZML/v2 enables the explicit allocation and use of pinned memory. Pinned memory is memory that is not movable nor swappable and thus can be directly accessed by the DMA engine of the accelerators. This functionality is exposed via the <code>zml.mem.DmaAllocator</code> which, combined with Zig’s explicit allocator model, enables unique optimizations and removes extraneous copies found in other frameworks.</p>\n<h2>Zero and overlapped copy primitives</h2>\n<p>Data transfers between host and accelerator now compose with <code>std.Io.Writer</code> via <code>zml.io.MemoryWriter</code>, enabling zero-copy and overlapped data movement across the board.</p>\n<p>For instance, loading a model from disk to GPU memory now happens at SSD speed when using <code>O_DIRECT</code>, even with staging through the system memory, since transfers are overlapped. This enables NVIDIA GPUDirect-like performance on raw POSIX.</p>\n<pre><code><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">$</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> bazel build<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>config</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-option syntax-shell\">=</span>release //examples/llm --@zml//platforms:cuda=true</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">$</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> bazel-bin/examples/llm/llm<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>model</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-option syntax-shell\">=</span>/var/models/meta-llama/Llama-3.1-8B-Instruct/</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">...</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">info</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">(llm</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> Selected backend: .cuda_fa2</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">info</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">(llm</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> Loaded tokenizer <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>181.256ms<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span></span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">info</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\">(llama</span><span class=\"syntax-meta syntax-function-call syntax-shell\"></span><span class=\"syntax-meta syntax-post-cmd syntax-shell\">)</span><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-support syntax-function syntax-colon syntax-shell\">:</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> Loaded weights <span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-begin syntax-shell\">[</span>14.96GiB, 1.165s, 12.83GiB/s<span class=\"syntax-keyword syntax-control syntax-regexp syntax-set syntax-end syntax-shell\">]</span></span>\n</span></span></code></pre>\n<h2>Userland Virtual File System</h2>\n<p>Thanks to injectable <code>std.Io</code>, ZML implements a full userland VFS built into the program. It supports local files, HTTP endpoints, S3 buckets and Hugging Face repositories. Concretely, this means that models can be loaded directly from each of those sources without downloading to disk first, regardless of the underlying FS implementation.</p>\n<p>Let’s try to register an HF implementation and load the tokenizer directly from Hugging Face:</p>\n<pre><code class=\"language-zig\"><span class=\"code-snippet\" data-language=\"Zig\">var vfs: zml.io.VFS = try .init(init.gpa, init.io);\ndefer vfs.deinit();\n\nvar hf_vfs: zml.io.VFS.HF = try .auto(init.gpa, init.io, &amp;http_client, init.environ_map);\ndefer hf_vfs.deinit();\ntry vfs.register(&quot;hf&quot;, hf_vfs.io());\n\n// Use the VFS IO from now on\nconst io = vfs.io();\n\nconst tokenizer: zml.Tokenizer = blk: {\n    const file = try std.Io.Dir.openFile(.cwd(), io, &quot;hf://Qwen/Qwen3-8B/tokenizer.json&quot;, .{});\n    defer file.close(io);\n    var reader = file.reader(init.gpa, &amp;.{});\n    const bytes = try reader.interface.readAlloc(init.gpa, try file.length(io));\n    defer init.gpa.free(bytes);\n    break :blk try .fromBytes(init.gpa, io, bytes);\n};\n</span></code></pre>\n<p>Or load the model directly from Hugging Face:</p>\n<pre><code><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">$</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> bazel-bin/examples/llm/llm<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>model</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-option syntax-shell\">=</span>hf://meta-llama/Llama-3.1-8B-Instruct</span>\n</span></span></code></pre>\n<h2>Powerful sharding primitives</h2>\n<p>Sharding is now a first-class citizen of the programming model instead of an implicit backend detail. We introduce a new public <code>zml.sharding</code> API with <code>PhysicalMesh</code>, <code>LogicalMesh</code>, <code>Strategy</code>, <code>Sharding</code>, and <code>Placement</code>. Compile / load / buffer APIs now take explicit sharding information and finally <code>zml.ops.manualComputation</code> expresses a shard-local primitive similar to JAX’s <code>shard_map</code>.</p>\n<p>It also fully leverages <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://openxla.org/shardy\">Shardy</a> or <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://research.google/blog/general-and-scalable-parallelization-for-neural-networks/\">GSPMD</a> based on the target platform transparently.</p>\n<h2>Pluggable Attention backend</h2>\n<p>ZML/v2 provides a pluggable attention backend system, giving a clean way to select and configure different attention implementations without rewriting model code around each kernel.</p>\n<p>Instead of baking backend-specific logic into every call site, <code>zml.attention</code> exposes an explicit <code>Backend</code> plus backend-typed <code>Parameters</code>, <code>Metadata</code>, and paged-attention <code>Context</code>, so the same high-level attention path can target vanilla behavior or optimized CUDA FlashAttention variants like Tri-Dao’s FA2 and FA3.</p>\n<p>The backend is selected automatically based on the platform and accelerator.</p>\n<p>In this release, we took the opportunity to integrate <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/zml/flash-attention/releases/tag/v2026.3.23\">FlashAttention 2 and 3 built on CUDA for <code>sm80</code> up to <code>sm121</code></a>.</p>\n<h2>Complete build sandboxing</h2>\n<p>Our build now runs entirely on the 100% hermetic LLVM toolchain <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/cerisier/toolchains_llvm_bootstrapped\">@llvm</a>. This enables full reproducibility, better cross-compilation support, and a more consistent development experience across platforms. This means that ZML supports remote execution on services such as <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.buildbuddy.io/\">BuildBuddy</a> or <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.nativelink.com/\">NativeLink</a>.</p>\n<p>On macOS, we no longer rely on Xcode nor Command Line Tools to build ZML. The macOS SDK is downloaded as part of the build.</p>\n<p>Cross compilation is also fully supported, enabling fully working containers for any supported ZML platform to be built right from a Mac.</p>\n<h2>//examples/llm</h2>\n<p>Try it today via the <code>llm</code> CLI:</p>\n<pre><code><span class=\"code-snippet\" data-language=\"Shell\"><span class=\"syntax-source syntax-shell syntax-bash\"><span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">$</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> bazel build<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>config</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-option syntax-shell\">=</span>release //examples/llm --@zml//platforms:cuda=true</span>\n<span class=\"syntax-meta syntax-function-call syntax-shell\"><span class=\"syntax-variable syntax-function syntax-shell\">$</span></span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-shell\"> bazel-bin/examples/llm/llm<span class=\"syntax-variable syntax-parameter syntax-option syntax-shell\"><span class=\"syntax-punctuation syntax-definition syntax-parameter syntax-shell\"> --</span>model</span><span class=\"syntax-keyword syntax-operator syntax-assignment syntax-option syntax-shell\">=</span>hf://Qwen/Qwen3.5-9B</span>\n</span></span></code></pre>\n",
  "content_markdown": "ZML is an inference stack built close to the hardware. It lowers models directly onto NVIDIA, AMD, TPU, and Trainium targets from a single codebase, without depending on and suffering from the Python-heavy runtime layers that most of the ecosystem is built around.\n\nThe guiding idea behind zml/v1 was simplicity: give ZML a model and its weights, and the system would take care of compilation, placement, and execution for you. That made the first version approachable and effective for standard deployments, but it also baked too much behavior into implicit global state. As the project pushed into partial compilation, custom passes, sharding, quantization, and more backend-specific execution paths, those implicit shortcuts became constraints. ZML/v2 is the rewrite that makes those concepts explicit: platform ownership, compilation, memory, IO, and placement are now first-class, so advanced use cases can be expressed directly instead of forced through workarounds.\n\n## Composability as a core principle\n\nZML/v2 is a complete rewrite of the framework with a focus on developer experience, performance and most importantly **composability**. This is a fundamental departure from the original design which was a lot more turnkey but could make more complex programs a bit harder than necessary.\n\nSo we’ve decided to strongly orient the design towards composability while also offering an uplift in performance.\n\n## Explicit over implicit\n\nThe new API centers around `zml.Platform`s, which is the main abstraction across accelerators, runtimes, IO etc. In ZML, a platform is instantiated and from then on used to transfer data, build, compile and execute programs.\n\nThis is how it all starts:\n\n```zig\nconst platform: *zml.Platform = try .auto(allocator, io, .{});\n```\n\nZML offers various platforms selection mechanisms: compile-time, runtime and manual. The automatic runtime selection is the default and will pick the best available platform on the system, but users can also choose to compile for a specific platform or manually create a platform with custom options.\n\nThe then built program can now run transparently on all comptime-time enabled platforms, which can be enabled via the `--@zml//platforms:{cuda,rocm,tpu,neuron}=true` build flags. Doing so will download the runtime, strip it to its bare minimum and embed it inside the binary sandbox.\n\nFor instance, here is the **entire** CUDA sandbox:\n\n```\n$ tree --du -h bazel-bin/examples/llm/llm.runfiles/+cuda_packages+libpjrt_cuda/sandbox/\n[2.9G]  bazel-bin/examples/llm/llm.runfiles/+cuda_packages+libpjrt_cuda/sandbox/\n├── [ 82M]  bin\n│   ├── [3.0M]  compat_probe\n│   ├── [ 40M]  nvlink\n│   └── [ 39M]  ptxas\n├── [2.8G]  lib\n│   ├── [409M]  compat\n│   │   ├── [ 11M]  libcudadebugger.so.1\n│   │   ├── [ 94M]  libcuda.so.1\n│   │   ├── [ 86M]  libnvidia-gpucomp.so.590.48.01\n│   │   ├── [ 24M]  libnvidia-nvvm70.so.4\n│   │   ├── [ 75M]  libnvidia-nvvm.so.4\n│   │   ├── [ 14K]  libnvidia-pkcs11-openssl3.so.590.48.01\n│   │   ├── [ 31M]  libnvidia-ptxjitcompiler.so.1\n│   │   └── [ 90M]  libnvidia-tileiras.so.590.48.01\n│   ├── [479M]  libcublasLt.so.13\n│   ├── [ 52M]  libcublas.so.13\n│   ├── [740K]  libcudart.so.13\n│   ├── [104M]  libcudnn_adv.so.9\n│   ├── [2.3M]  libcudnn_cnn.so.9\n│   ├── [233M]  libcudnn_engines_precompiled.so.9\n│   ├── [ 26M]  libcudnn_engines_runtime_compiled.so.9\n│   ├── [3.5M]  libcudnn_graph.so.9\n│   ├── [ 56M]  libcudnn_heuristic.so.9\n│   ├── [ 37M]  libcudnn_ops.so.9\n│   ├── [126K]  libcudnn.so.9\n│   ├── [286M]  libcufft.so.12\n│   ├── [4.4M]  libcupti.so.13\n│   ├── [136M]  libcusolver.so.12\n│   ├── [162M]  libcusparse.so.12\n│   ├── [218M]  libnccl.so.2\n│   ├── [ 95M]  libnvJitLink.so.13\n│   ├── [4.2M]  libnvrtc-builtins.so.13.1\n│   ├── [109M]  libnvrtc.so.13\n│   ├── [ 40M]  libnvshmem_host.so.3\n│   ├── [ 39K]  libnvtx3interop.so\n│   ├── [383M]  libpjrt_cuda.so\n│   ├── [2.9M]  libzmlxcuda.so.0\n│   ├── [118K]  libz.so.1\n│   ├── [ 72K]  nvshmem_bootstrap_uid.so.3\n│   └── [1023K]  nvshmem_transport_ibrc.so.4\n└── [ 77M]  nvvm\n    ├── [ 77M]  bin\n    │   └── [ 77M]  cicc\n    └── [458K]  libdevice\n        └── [454K]  libdevice.10.bc\n```\n\n## Pinned Memory Allocators\n\nZML/v2 enables the explicit allocation and use of pinned memory. Pinned memory is memory that is not movable nor swappable and thus can be directly accessed by the DMA engine of the accelerators. This functionality is exposed via the `zml.mem.DmaAllocator` which, combined with Zig’s explicit allocator model, enables unique optimizations and removes extraneous copies found in other frameworks.\n\n## Zero and overlapped copy primitives\n\nData transfers between host and accelerator now compose with `std.Io.Writer` via `zml.io.MemoryWriter`, enabling zero-copy and overlapped data movement across the board.\n\nFor instance, loading a model from disk to GPU memory now happens at SSD speed when using `O_DIRECT`, even with staging through the system memory, since transfers are overlapped. This enables NVIDIA GPUDirect-like performance on raw POSIX.\n\n```\n$ bazel build --config=release //examples/llm --@zml//platforms:cuda=true\n$ bazel-bin/examples/llm/llm --model=/var/models/meta-llama/Llama-3.1-8B-Instruct/\n...\ninfo(llm): Selected backend: .cuda_fa2\ninfo(llm): Loaded tokenizer [181.256ms]\ninfo(llama): Loaded weights [14.96GiB, 1.165s, 12.83GiB/s]\n```\n\n## Userland Virtual File System\n\nThanks to injectable `std.Io`, ZML implements a full userland VFS built into the program. It supports local files, HTTP endpoints, S3 buckets and Hugging Face repositories. Concretely, this means that models can be loaded directly from each of those sources without downloading to disk first, regardless of the underlying FS implementation.\n\nLet’s try to register an HF implementation and load the tokenizer directly from Hugging Face:\n\n```zig\nvar vfs: zml.io.VFS = try .init(init.gpa, init.io);\ndefer vfs.deinit();\n\nvar hf_vfs: zml.io.VFS.HF = try .auto(init.gpa, init.io, &http_client, init.environ_map);\ndefer hf_vfs.deinit();\ntry vfs.register(\"hf\", hf_vfs.io());\n\n// Use the VFS IO from now on\nconst io = vfs.io();\n\nconst tokenizer: zml.Tokenizer = blk: {\n    const file = try std.Io.Dir.openFile(.cwd(), io, \"hf://Qwen/Qwen3-8B/tokenizer.json\", .{});\n    defer file.close(io);\n    var reader = file.reader(init.gpa, &.{});\n    const bytes = try reader.interface.readAlloc(init.gpa, try file.length(io));\n    defer init.gpa.free(bytes);\n    break :blk try .fromBytes(init.gpa, io, bytes);\n};\n```\n\nOr load the model directly from Hugging Face:\n\n```\n$ bazel-bin/examples/llm/llm --model=hf://meta-llama/Llama-3.1-8B-Instruct\n```\n\n## Powerful sharding primitives\n\nSharding is now a first-class citizen of the programming model instead of an implicit backend detail. We introduce a new public `zml.sharding` API with `PhysicalMesh`, `LogicalMesh`, `Strategy`, `Sharding`, and `Placement`. Compile / load / buffer APIs now take explicit sharding information and finally `zml.ops.manualComputation` expresses a shard-local primitive similar to JAX’s `shard_map`.\n\nIt also fully leverages [Shardy](https://openxla.org/shardy) or [GSPMD](https://research.google/blog/general-and-scalable-parallelization-for-neural-networks/) based on the target platform transparently.\n\n## Pluggable Attention backend\n\nZML/v2 provides a pluggable attention backend system, giving a clean way to select and configure different attention implementations without rewriting model code around each kernel.\n\nInstead of baking backend-specific logic into every call site, `zml.attention` exposes an explicit `Backend` plus backend-typed `Parameters`, `Metadata`, and paged-attention `Context`, so the same high-level attention path can target vanilla behavior or optimized CUDA FlashAttention variants like Tri-Dao’s FA2 and FA3.\n\nThe backend is selected automatically based on the platform and accelerator.\n\nIn this release, we took the opportunity to integrate [FlashAttention 2 and 3 built on CUDA for `sm80` up to `sm121`](https://github.com/zml/flash-attention/releases/tag/v2026.3.23).\n\n## Complete build sandboxing\n\nOur build now runs entirely on the 100% hermetic LLVM toolchain [@llvm](https://github.com/cerisier/toolchains_llvm_bootstrapped). This enables full reproducibility, better cross-compilation support, and a more consistent development experience across platforms. This means that ZML supports remote execution on services such as [BuildBuddy](https://www.buildbuddy.io/) or [NativeLink](https://www.nativelink.com/).\n\nOn macOS, we no longer rely on Xcode nor Command Line Tools to build ZML. The macOS SDK is downloaded as part of the build.\n\nCross compilation is also fully supported, enabling fully working containers for any supported ZML platform to be built right from a Mac.\n\n## //examples/llm\n\nTry it today via the `llm` CLI:\n\n```\n$ bazel build --config=release //examples/llm --@zml//platforms:cuda=true\n$ bazel-bin/examples/llm/llm --model=hf://Qwen/Qwen3.5-9B\n```\n",
  "dateCreated": "2026-09-08T10:17:10.166315+00:00",
  "date_created": "2026-03-24T15:00:00+00:00",
  "date_modified": "2026-03-24T15:00:00+00:00",
  "date_published": "2026-03-24T15:00:00+00:00",
  "description": "ZML is an inference stack built close to the hardware. It lowers models directly onto NVIDIA, AMD, TPU, and Trainium targets from a single codebase, without depending on and suffering from the Python-heavy runtime layers that most of the…",
  "external_url": "https://zml.ai/posts/zml-v2/",
  "git": {
    "commit": "ebb0941c5c06a2ab2377342d607535262a3e969e",
    "path": "items/zml-ai/2026/03/2026-03-24-introducing-zml-v2.md",
    "permalink": "https://github.com/aymericbeaumet/aggr-instance/blob/ebb0941c5c06a2ab2377342d607535262a3e969e/items/zml-ai/2026/03/2026-03-24-introducing-zml-v2.md"
  },
  "id": "urn:aggr:item:588bd1a5ac856ad69bc70c27145fa71c3dce5b9e",
  "isBasedOn": {
    "@id": "https://zml.ai/posts/zml-v2/"
  },
  "mainEntity": {
    "@id": "https://zml.ai/posts/zml-v2/",
    "@type": "CreativeWork",
    "archivedAt": {
      "@id": "https://aggr.aymericbeaumet.com/items/zml-ai/2026-03-24-introducing-zml-v2/#webpage"
    },
    "dateModified": "2026-03-24T15:00:00+00:00",
    "datePublished": "2026-03-24T15:00:00+00:00",
    "headline": "Introducing ZML/v2",
    "timeRequired": "PT6M",
    "url": "https://zml.ai/posts/zml-v2/",
    "wordCount": 1154
  },
  "name": "Archived snapshot: Introducing ZML/v2",
  "preview": null,
  "reading_minutes": 6,
  "replicated_at": null,
  "source": "zml-ai",
  "source_name": "ZML - Model to Metal",
  "summary": "ZML is an inference stack built close to the hardware. It lowers models directly onto NVIDIA, AMD, TPU, and Trainium targets from a single codebase, without depending on and suffering from the Python-heavy runtime layers that most of the ecosystem is built around. The guiding idea behind zml/v1 was simplicity: give ZML a model and its weights, and the system would take care of compilation, placement, and execution for you. That made the first version approachable and effective for standard deployments, but it also baked too much behavior into implicit global state. As the project pushed into partial compilation, custom passes, sharding, quantization, and more backend-specific execution paths, those implicit shortcuts became constraints. ZML/v2 is the rewrite that makes those concepts explicit: platform ownership, compilation, memory, IO, and placement are now first-class, so advanced use cases can be expressed directly instead of forced through workarounds.",
  "tags": [],
  "temporalCoverage": "2026-09-08T10:17:10.166315+00:00",
  "title": "Introducing ZML/v2",
  "url": "https://aggr.aymericbeaumet.com/items/zml-ai/2026-03-24-introducing-zml-v2/",
  "word_count": 1154
}