Export: training and serving, Julia native
The same forward that trained becomes the servable program. Nothing leaves the Julia and Reactant ecosystem between the first train! and the served bundle.
using ReactantServerExport # the extension that provides the backendn = Nitro(e; checkpoint = "runs/x/best.jld2", data = (;)) # no training in this processexport_model(n, ReactantServerBundle(); dir = "export_out", name = "mnist_v1")export_model takes a Nitro, not a path, so a model's export code never loads a checkpoint itself. data = (;) skips build_data entirely, so an export process does not have to produce a training split to get started.
The wire contract
Export hooks declare what clients send and receive:
export_inputsandexport_outputsdeclare the wire shapes and dtypes.export_preprocessconverts what clients send, usuallyUInt8pixels, into what the model trains on, usually normalizedFloat32. This happens inside the traced graph, so what ships isexport_preprocess ∘ forwardas one program and a client never has to reproduce your normalization.export_postprocessandexport_client_inputs/export_client_outputscover the other side of the seam when the served contract differs from the traced one.
Axes are the one place the two worlds disagree, and the framework owns the translation: ExportSpec is 1-based Julia axes like every other axis statement in the package, and the backend's IOSpec is 0-based network axes.
What a bundle is
The artifact is a ReactantServer StableHLO bundle:
manifest.yamlweights.safetensors- one
model[.bN].mlirper compiled batch size model.jl, when the model ships a postprocess
Export is a single-device CPU trace, so it needs no GPU and no accelerator lease. Provenance (config, seed, preset, framework version, and on a dirty tree a full working-tree patch) lands in the bundle automatically, so a served artifact can be traced back to the code that produced it.
Caveats worth knowing up front
A view-shaped program output has to be copyed before it leaves the traced graph, or the bundle carries a wrapper rather than an array. This does not apply to parameters, which the flat layout reconstructs through a copy already.
The backend lives behind a weak dependency, ReactantServerExport, so nothing in src/ knows the bundle format exists and a deployment that never exports pays nothing for it.