Subnet 2 (Bittensor): verifiable inference with zk-ML, miner and validator setup
Verifiable inference on Bittensor
At a glance
- What is it?
- Subnet 2 turns AI predictions into zero-knowledge proofs so validators can check that a specific model produced an output. Here is how the Rust miner and validator fit together, how to install them, and where the design runs into trouble.
- Who is it for?
- Adopt Subnet 2 if you can run a Rust binary or the published container and you accept that the proof, not the raw prediction, is the product being scored. Skip it if you want GPU-throughput inference serving, or if you need documented rollback and version-pinning procedures, because the README describes an auto-update mechanism and a Docker tag that tracks latest without explaining how to step back to 14.14.2.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 1, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What Subnet 2 is actually verifying
Most inference marketplaces ask you to trust the operator. Subnet 2 asks you to check a proof. The README frames the project as a Proof-of-Inference system for Bittensor, where zk-ML converts an AI model into what it calls a fingerprint, a circuit that can be used to confirm a prediction came from that specific model. That is the whole point of the subnet: the artifact under review is not the text or number a miner returns, it is the cryptographic evidence that a declared model produced it.
The audience follows from that. Miners need a model they can circuitize, meaning it has to be expressible as a proving circuit, and they need to care about proof generation time. Validators need to run verification cheaply enough that scoring many miners stays viable. The README states that zero-knowledge proofs are generally more CPU computationally intensive, which opens the door to non-GPU miners, while the stated end goal is to push proving systems toward GPU-based operations. If you are looking for a subnet to point a rented A100 at and serve tokens as fast as possible, this is a different kind of job.
Miners, validators and what gets scored
The split is conventional for Bittensor, but the payload is not. Validators produce input data and distribute inference requests across miners. Miners receive that input, run a verifiable model that has been converted into a zero-knowledge circuit, and return the generated content along with the proof. Validators then verify the authenticity of the proof and score the result.
The scoring is where the design gets opinionated. According to the README, the reward mechanism scores initial AI predictions on cryptographic integrity and the time to generate zk-proofs along with the outputs, rather than solely on end results. Proof size and response time are named as performance metrics. That means a miner with a marginally worse model but a much faster prover can outrank a slower, more accurate one. It also means the validator's cost is bounded by verification rather than by re-running inference, which is the argument for the architecture: validators do not need to reproduce the model's work to know it happened.
Communication runs over HTTP and QUIC through btlightning, a separate library in the same organization. The workspace splits the logic across seven crates, including sn2-verify for verification and sn2-circuit-store for circuit handling, so the verification path is not buried inside the miner binary.
Installing sn2-miner and sn2-validator
The prerequisites table lists Rust, PM2 and btcli. Rust is only needed for source builds; the install script downloads a pre-built release, checks the SHA256 checksum and places the binary in /usr/local/bin. The script auto-detects the platform, so the same line works on the machines the project supports.
curl -fsSL https://raw.githubusercontent.com/inference-labs-inc/subnet-2/main/install.sh | bashTo install only one role, pass the binary name as an argument. This is the version to use on a validator host that should never run miner code.
curl -fsSL https://raw.githubusercontent.com/inference-labs-inc/subnet-2/main/install.sh | bash -s -- sn2-validator
curl -fsSL https://raw.githubusercontent.com/inference-labs-inc/subnet-2/main/install.sh | bash -s -- sn2-minerTestnet builds come from the testnet branch and take a NETWORK variable. Note that the variable is set before bash, not passed as an argument.
curl -fsSL https://raw.githubusercontent.com/inference-labs-inc/subnet-2/testnet/install.sh | NETWORK=testnet bash -s -- sn2-minerIf you prefer to compile, the workspace builds both binaries in one pass. The README states the outputs land at target/release/sn2-validator and target/release/sn2-miner.
git clone https://github.com/inference-labs-inc/subnet-2.git
cd subnet-2
cargo build --release --bin sn2-validator --bin sn2-minerRegistration happens through btcli against netuid 2 on finney, using your coldkey and hotkey names. The README points to docs/shared_setup_steps.md for the surrounding setup.
btcli subnet register --subtensor.network finney --netuid 2 --wallet.name {your_coldkey} --wallet.hotkey {your_hotkey}Running the miner under PM2 is a single make target that takes the wallet names as variables. The direct PM2 form uses --kill-timeout 3000, which matters because a prover that ignores SIGTERM would otherwise be killed mid-proof.
make pm2-miner WALLET_NAME={your_miner_key_name} WALLET_HOTKEY={your_miner_hotkey_name}The Docker route avoids the Rust toolchain entirely. The README gives a compose file with two services, the miner and watchtower, and the miner image is ghcr.io/inference-labs-inc/subnet-2:latest with port 8091 published and your .bittensor directory mounted at /home/subnet2/.bittensor. The command line passes --wallet-name, --wallet-hotkey and --netuid 2. Watchtower is configured with --interval 60 --cleanup --label-enable and only touches containers carrying the enable label, which is why the miner service sets com.centurylinklabs.watchtower.enable=true. Expect the container to restart on its own when a new image appears.
The auto-update mechanism is the sharpest edge here
The README states that the published binaries include a built-in auto-update mechanism that polls for new releases every 5 minutes and performs atomic binary replacement so PM2 restarts with the new version. The Docker path achieves something similar through watchtower on a 60 second interval. Both are convenient, and both mean the version you validated in staging is not necessarily the version running tomorrow.
The README does not document rollback. There is no described command to pin a binary to a specific release, no documented way to disable the poll, and no stated procedure for reverting to 14.14.2 if 14.14.3 misbehaves. For a miner whose stake is tied to proof generation, that is a real operational exposure. If you need determinism, the source build path is the one that gives it to you, because a binary you compiled stays put until you rebuild it.
A second constraint sits in the Dockerfile: the runtime stage installs jq, aria2, curl, ca-certificates, gosu and libssl3, and the entrypoint briefly elevates to apply a PUID remap before dropping to the subnet2 user. The file carries a comment telling you to override the entrypoint at your own risk because the default invocation drops privileges. If you replace the entrypoint for your own orchestration, you own that decision.
Proof cost is the limitation, not an implementation detail
The README is candid that zero-knowledge proofs are generally more CPU computationally intensive, and it treats non-GPU participation as an opportunity rather than a target state. The practical consequence is that a miner is optimizing a proving pipeline, not an inference server. Model architectures that circuitize cleanly will beat architectures that do not, even when the latter are better models. If your model depends on operations that are awkward to express as a circuit, Subnet 2 is the wrong venue for it, and no amount of tuning the miner binary changes that.
The validator side has a matching constraint that the README does not quantify. Scoring rewards proof size and response time, so validators are implicitly asked to make latency judgements about proofs. Nothing in the README explains how a slow but valid proof is treated relative to a fast one, or what happens when a proof verifies but the miner's output is poor. A validator operator should read docs/shared_setup_steps.md and the sn2-verify crate before assuming the scoring function matches their expectations. I would also treat the absence of documented rollback as a limitation in its own right for anyone running this on infrastructure they cannot rebuild quickly.
How this differs from running inference behind an API
The obvious alternative is a conventional inference endpoint, where you send input to a server and receive output, with trust placed in the operator. Subnet 2 inverts that: the miner returns a proof alongside the content, and the validator checks the proof rather than re-running the model. The difference in cost profile is the interesting part. A conventional endpoint scales with GPU time for every request. Subnet 2 shifts work to proof generation on the miner and verification on the validator, which is why the README can claim reduced computational burden on validators.
Within Bittensor itself, the contrast is with subnets that score outputs directly. Those can accept any model a miner wants to run, because nothing needs to be circuitized. Subnet 2 trades that openness for verifiability: you get cryptographic assurance about which model produced a prediction, and you pay for it in the set of models you can use and in the time each proof takes. Neither approach is strictly better. They answer different questions, and the question Subnet 2 answers is provenance.
Licence, maintenance and what the repository tells you
The project is MIT licensed, and the workspace Cargo.toml declares license = "MIT" with a LICENSES/ directory at the top level. MIT is permissive, so integrating the crates into your own tooling is straightforward, but the usual caveat applies: the licence covers the code, not the models you circuitize or the network you register on. Nothing here is legal advice, and if you plan to redistribute a modified miner you should read the LICENSE and LICENSES/ files yourself.
The last push to the default branch was on 2026-09-09, and release 14.14.3 was published on 2026-09-08, with a testnet tag the same day. That is recent activity, and the repository is not archived. The upgrade cost is unusual, though: because the binary polls for releases every 5 minutes and replaces itself atomically, upgrades are not a task you schedule. The cost is the opposite, namely that you must be prepared for the running version to change without your involvement. On the Docker side, watchtower with --cleanup removes the old image after each update, so you cannot fall back to a previous container without pulling it again by digest.
Editorial conclusion
Adopt Subnet 2 if you can run a Rust binary or the published container and you accept that the proof, not the raw prediction, is the product being scored. Skip it if you want GPU-throughput inference serving, or if you need documented rollback and version-pinning procedures, because the README describes an auto-update mechanism and a Docker tag that tracks latest without explaining how to step back to 14.14.2. Before registering a hotkey, read docs/shared_setup_steps.md and confirm what the validator does with a proof that verifies but arrives slowly.
Frequently asked questions
What is Subnet 2 on Bittensor?
It is a Bittensor subnet that builds a Proof-of-Inference system, where zk-ML converts an AI model into a circuit that can verify a prediction came from that specific model. Miners generate verified predictions and validators check the proofs and score the results.
How do I install Subnet 2's miner and validator?
The README's install script detects your platform, downloads the latest release, verifies its SHA256 checksum and installs to /usr/local/bin. Passing sn2-miner or sn2-validator as an argument installs only that binary, and Docker images are published for both roles if you would rather skip the Rust toolchain.
Does Subnet 2 need a GPU to mine?
The README states that zero-knowledge proofs are generally more CPU computationally intensive, which it presents as an opportunity for non-GPU miners to participate. It also says the end goal is to further incentivize proving systems optimized for GPU-based operations.
How do Subnet 2 miners and validators communicate?
They are native Rust binaries that communicate over both HTTP and QUIC, using the btlightning library. Validators distribute inference requests to miners and receive predictions with proofs in return.
Which licence does Subnet 2 use?
The repository is MIT licensed, and the workspace Cargo.toml declares license = "MIT" with a LICENSES/ directory at the top level. That covers the code, not the models you circuitize or your network registration.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/inference-labs-inc-subnet-2)