For the complete documentation index, see llms.txt. This page is also available as Markdown.

Apache TVM

Apache TVM 0.8 integration for optimized model inference

Apache TVM

The nd4j-tvm module integrates Apache TVM 0.8 for compiler-optimized model inference. TVM is a machine learning compiler that takes a model from a framework (PyTorch, TensorFlow, ONNX, MXNet, etc.), applies hardware-specific optimization passes (operator fusion, layout optimization, auto-tuning), and compiles it to a native binary for a target hardware backend.

The resulting compiled module is loaded in Java via the TVM runtime and nd4j-tvm bindings.


What TVM Provides

TVM operates in two phases:

  1. Compile-time (Python): load a model, apply optimization passes, auto-tune for target hardware, and export a compiled module (.so shared library + metadata JSON)

  2. Runtime (Java): load the compiled module, provide input tensors, run the optimized kernel

The key benefit is that TVM can produce kernels significantly faster than the original runtime, especially on CPUs with specific instruction sets (AVX-512, ARM NEON) and on GPUs and NPUs.


Maven Dependency

<dependency>
    <groupId>org.nd4j</groupId>
    <artifactId>nd4j-tvm</artifactId>
    <version>${dl4j.version}</version>
</dependency>

The module includes the TVM 0.8 runtime library. The compilation step (Python) must be done separately.


Step 1: Compile Your Model with TVM (Python)

TVM model compilation is done in Python using the tvm Python package.

Install TVM

Compile an ONNX Model

Compile a PyTorch Model

Auto-Tuning for Better Performance

Auto-tuning searches for the best kernel configurations for your hardware. This can take minutes to hours but typically improves inference speed significantly:


Step 2: Load and Run the Compiled Module in Java


TvmRunner Builder Options

TvmRunner is AutoCloseable. Use try-with-resources to ensure native resources are released:


Supported Target Backends

TVM can compile for many hardware targets. The target string is specified at compile time (Python):

Hardware
TVM Target String

x86 CPU (generic)

"llvm"

x86 with AVX2

"llvm -mcpu=core-avx2"

x86 with AVX-512

"llvm -mcpu=skylake-avx512"

ARM CPU

"llvm -device=arm_cpu -target=arm-linux-gnueabihf"

ARM64

"llvm -device=arm_cpu -target=aarch64-linux-gnu"

CUDA GPU

"cuda"

Vulkan

"vulkan"

Metal (macOS)

"metal"

WebAssembly

"wasm"

Compile-time target selection is independent of the Java runtime module; the compiled .so is target-specific.


Troubleshooting

UnsatisfiedLinkError loading the .so: ensure the compiled .so was built for the same target CPU/OS as where it is being loaded. Cross-compiled binaries (e.g., compiled on x86, loaded on ARM) will fail.

Input name mismatch: the input name passed to runner.exec() must match the name used during TVM compilation. If the name was "input_1" in the ONNX model, use "input_1" in the Java map.

Performance not as expected: if auto-tuning was not performed, performance may be similar to unoptimized execution. Run auto-tuning for the target hardware to see TVM's full benefit.

TVM version mismatch: the nd4j-tvm module bundles TVM 0.8 runtime libraries. A compiled module from a different TVM version may not load. Compile with TVM 0.8 to match.

Last updated

Was this helpful?