Installing
The toolkit ships as a Python wheel. The first bundle I installed carried version 2.1.0, two minor versions behind the current release at the time, and its default wheels were Linux only, for CPython 3.12 and 3.13.
A macOS arm64 wheel for CPython 3.12 does exist in the public releases, and has since v2.3.0 on 19 August 2026. If you are on an Apple Silicon laptop, install from the current release rather than an older bundle.
What I wanted on day one and did not find: a copy and paste install command, a platform support matrix, and a link from the documentation to the examples repository. None of that is hard to add, and all of it would shorten the first hour for the next person.
Reading the API
The API reference itself is good. It renders the mathematics, calls out dtypes explicitly, warns about the features @ weights.T convention, and notes a 4,096 byte page alignment requirement that you would otherwise find the hard way.
The most useful thing I did early was list what the package actually exports. This was the closed release I started on.
| What | Count |
|---|---|
Public names in dir(qant) | 29 |
| Callable | 27 |
Ending in _fprop | 14 |
Containing bprop, backward or grad | 0 |
That table says more about the hardware than any diagram. The device is forward only. You train on the host and run inference on the card, and once you see that, the whole workflow makes sense.
The toolkit goes open source
On 23 September 2026 Q.ANT published the toolkit on GitHub under Apache 2.0, at version 2.3.1. Three things worth knowing if you build it yourself:
- It has a CPU backend that simulates the device, built with
maturin build --release -F cpu-backend. It needs a Rust toolchain. - The build fails until you fetch the git submodules (
git clone --recurse-submodules). The error names a missingdlpack.h. - The functions moved into submodules.
calc_kan_layer_fpropis nowai.calc_kan_layer_fprop, andinit_npuisgeneric.init_npu. The exported bundle accepts both layouts.
Reading the source also corrected something I had written. The device does not compute an exact cosine. The documentation calls it tcos, a periodic shape similar to a cosine. The CPU emulator substitutes an exact one.
Rerunning everything
In October I threw away every earlier number and reran all 106 configurations with the code this site exports. The reason: my earlier results said “NPU” without recording what the toolkit had actually run on.
The toolkit can tell you. Its driver string reads cpu-backend on the emulator, and a real card reports its own serial and firmware. The bundle now saves that report with every result.
The rerun answered the open question too. Through the emulator, 105 of the 106 runs reproduce an old “NPU” number bit for bit. The one exception draws its training data from a different seed, because the old script fixed that seed and the bundle does not. So the earlier results were emulator runs. Nothing on this site comes from photonic hardware yet, and the Lab says so at the top.
The examples
The examples repository holds six Python examples: introduction, digit_recognition, fourier_network, image_recognition, image_segmentation and parallel_execution. The Fourier network example is the one this site grew out of. It starts from a small network, [1, 4, 1] with grid 4, 69 parameters. The Lab is what happened when I kept pushing on it.
Things I got wrong
I am keeping these on the record because each one is a trap someone else will walk into.
“All 29 toolkit functions end in fprop.” False. 29 is the count of public names. 27 are callable, and 14 of those end in _fprop. Of the other 15 names, three are compute primitives, ten are housekeeping and two are submodules.
“There is no ARM build.” Out of date. The arm64 macOS wheel exists. The accurate point is narrower: the bundle I started from shipped an older release.
A bfloat16 rounding example. I once wrote that 1.24204 rounds to 1.23438 in bfloat16. It does not. It rounds to 1.2421875. The correct example is 1.23800, which rounds down to 1.23438. You can check it with the slider in the Primer.
“All the runs clustered.” Overstated. In the 64 run architecture sweep, only 16 runs landed in the tight band. The honest claim is narrower and is written up in the Lab.
A mislabelled readout. An early widget showed a CPU float32 number under a label that implied it came from the hardware. Every number on this site now names the backend that produced it.
“Measured on the photonic NPU.” Wrong, and the biggest one. Those runs used the toolkit’s CPU emulator, and I had not checked. Every result now carries the toolkit’s own report of what it ran on.
“A cosine is not something the chip approximates.” Also wrong. The hardware’s shape is cosine-like, not exact.
What I would tell someone starting today
- Install from the current release, not from an older bundle.
- Run
dir()on the package before reading anything else. - Train on the host, and treat the device as an inference target.
- Tune the learning rate before you touch the architecture.
- Know the bfloat16 floor before you chase a lower loss.
- Record what your code actually ran on, every time.