From zero to running your own UNFED AI cluster in minutes. This guide walks through local development setup.
Required for all node types. Install via your system package manager or pyenv.
With CUDA support for GPU nodes. CPU works for registry and daemon nodes.
HuggingFace-compatible models with supported UNFED runtime architecture. We recommend ./models/Qwen2.5-Coder-0.5B-Instruct for text and HuggingFaceTB/SmolVLM-256M-Instruct for multimodal testing.
pip install torch safetensors grpcio grpcio-tools protobuf
pip install transformers # for model downloading
pip install fastapi uvicorn websockets # for web dashboard
pip install web3 # for on-chain staking (optional)
| Node Type | CPU | RAM | GPU | Notes |
|---|---|---|---|---|
| Registry | 1 vCPU | 1-2 GB | No | For larger pools use 2 vCPU / 4 GB. |
| Daemon | 2 vCPU | 4 GB | No | Persistent disk recommended for SQLite chain DB. |
| MPC Node A | 4 vCPU | 8-16 GB | Recommended | Entry privacy node; usually the heavier MPC side. |
| MPC Node B | 4 vCPU | 8-16 GB | Recommended | Peer privacy node; keep low latency to Node A. |
| Compute (text shard) | 4+ vCPU | 8-16 GB | Recommended | One process per shard index. |
| Vision shard | 4+ vCPU | 12-24 GB | Preferred | Needed for multimodal image paths. |
Use unfed-tools to inspect and split a model into shards.
See what you're working with: architecture, layer count, parameter count.
python -m tools inspect /path/to/model
Split the model into N text shards (and optionally a vision shard
for multimodal models). This creates a shards/ directory
with individual weight files and a v2 manifest.
python -m tools split /path/to/model \
--output shards_smolvlm \
--num-text-shards 2
Confirm that the shards are valid and the manifest is correct.
python -m tools verify shards_smolvlm
Model compatibility: UNFED currently targets decoder-style
text models that map to the generic runtime blocks (Qwen/Llama/Mistral-style)
and vision-language models via the supported split paths (for example SmolVLM).
New models should pass tools inspect + tools verify
and a short prompt sanity test before production rollout.
Practical status: the local testnet flow in this repo is
validated with ./models/Qwen2.5-Coder-0.5B-Instruct (text) and
HuggingFaceTB/SmolVLM-256M-Instruct (vision-language).
The registry is the cluster coordinator — start it first.
{
"name": "My UNFED Pool",
"chain_rpc_url": "http://localhost:8545",
"escrow_contract_address": "0x<from deployed.env>",
"staking_token_address": "0x<from deployed.env>",
"operator_private_key": "0x<operator private key>",
"daemon_required_count": 1
}
Token name is not required: you only provide
staking_token_address. The registry/escrow reads token metadata
(like symbol/name) directly from the ERC-20 contract on-chain.
python -m network.registry_server \
--port 50050 \
--cluster-config cluster_config.json
Important: this starts only the registry service (gRPC). If you also want the browser UI for easier querying, start the web server separately:
python -m web.server --port 8080 --registry localhost:50050
Policy scope: cluster_config.json is loaded by
the registry process at startup. Quorum knobs like
daemon_required_count are registry-local policy.
Stake amount control: registry-side
default_min_stake defines the minimum stake required for node
admission (compute/vision/MPC). If a node is below this threshold, registration
is rejected until re-staked.
On-chain admission auth (new): when on-chain escrow is enabled,
compute/vision/MPC/daemon registration must include an EVM signature over the canonical
registration payload (node identity, address, model, shard, share-signing key,
timestamp, nonce). The recovered signer must match node_id.
# Recommended: store stake key in a file (OPSEC)
umask 077
printf '%s' "0x<staked wallet private key>" > ~/.unfed/node_stake.key
export UNFED_STAKE_EVM_PRIVATE_KEY_FILE=~/.unfed/node_stake.key
Tip: The registry serves the model manifest to nodes
automatically. Point --shards-dir at the split output if
you want manifest auto-discovery.
The chain daemon records compute shares and produces settlement blocks.
export UNFED_STAKE_EVM_PRIVATE_KEY_FILE=~/.unfed/daemon_stake.key
python -m network.daemon_node \
--port 50070 \
--registry localhost:50050 \
--eth-address 0x<daemon staked wallet address> \
--db ~/.unfed/chain.db
The daemon connects to the registry, syncs share chain state, and begins accepting shares from compute nodes. Settlement blocks are produced approximately every 10 seconds.
Pick the node type you want to run and follow its exact startup flow.
Strict startup order: start nodes in this order to avoid readiness and admission failures.
full_output_2pc and input MPC)Readiness gate: if your client policy requires MPC (for example UNFED_REQUIRE_MPC=1), model status stays INCOMPLETE until at least one healthy input MPC pair and one healthy output MPC pair are registered (the same A/B pair can advertise both).
Reproducibility rule: in on-chain mode, stake each node wallet before startup and always pass both:
UNFED_STAKE_EVM_PRIVATE_KEY_FILE (or UNFED_STAKE_EVM_PRIVATE_KEY)--eth-address matching that staked wallet addressUse this for cluster coordination, admission, and adjudication.
Start commandpython -m network.registry_server \
--port 50050 \
--cluster-config cluster_config.json
Tutorial: start this first, then start daemon and workers. If you want a convenient client UI, also run web.server in a separate process.
Use this for sharechain persistence, block production, and fee telemetry.
Start commandexport UNFED_STAKE_EVM_PRIVATE_KEY_FILE=~/.unfed/daemon_stake.key
python -m network.daemon_node \
--port 50070 \
--registry localhost:50050 \
--eth-address 0x<daemon staked wallet address> \
--db ~/.unfed/chain.db
Tutorial: start after registry, before compute/MPC nodes.
Use this for normal text shard execution. Run one process per shard index.
Shard 0 exampleexport UNFED_STAKE_EVM_PRIVATE_KEY_FILE=~/.unfed/node0_stake.key
python -m node.server \
--shard-index 0 \
--port 50051 \
--model-type smolvlm \
--shards-dir shards_smolvlm \
--registry localhost:50050 \
--eth-address 0xNodeAddress1
Shard 1 example
export UNFED_STAKE_EVM_PRIVATE_KEY_FILE=~/.unfed/node1_stake.key
python -m node.server \
--shard-index 1 \
--port 50052 \
--model-type smolvlm \
--shards-dir shards_smolvlm \
--registry localhost:50050 \
--eth-address 0xNodeAddress2
Tutorial: start all required shard indices for your model.
Use this only for multimodal pipelines that require a vision encoder path.
Vision shard exampleexport UNFED_STAKE_EVM_PRIVATE_KEY_FILE=~/.unfed/vision_stake.key
python -m node.server \
--shard-index 0 \
--port 50060 \
--model-type smolvlm_vision \
--shards-dir shards_smolvlm \
--registry localhost:50050 \
--eth-address 0xVisionNodeAddress
Tutorial: run alongside text compute nodes for image + text requests.
Use this when you want shard-0 privacy via secret sharing.
Start Node B first# Start MPC Node B first
export UNFED_STAKE_EVM_PRIVATE_KEY_FILE=~/.unfed/mpcb_stake.key
python -m network.mpc_shard0 \
--role B --port 50063 \
--peer localhost:50061 \
--registry localhost:50050 \
--shards-dir shards_smolvlm \
--eth-address 0xMPCBAddress
# Then start MPC Node A
export UNFED_STAKE_EVM_PRIVATE_KEY_FILE=~/.unfed/mpca_stake.key
python -m network.mpc_shard0 \
--role A --port 50061 \
--peer localhost:50063 \
--registry localhost:50050 \
--shards-dir shards_smolvlm \
--eth-address 0xMPCAddress
Tutorial: once MPC is running, route shard-0 traffic to MPC A.
Before exposing any node publicly, run preflight and enforce TLS.
python -m scripts.testnet_preflight node \
--advertise 203.0.113.42:50051 \
--tls-cert /path/to/server.crt \
--tls-key /path/to/server.key
Tutorial: treat preflight failures as NO-GO for rollout.
Detailed config docs moved: to keep this page focused on startup, full per-node config documentation now lives in a dedicated route with value-by-value explanations.
Open Config Reference → for registry, daemon, compute, vision, and MPC config fields.
Staking note: if on-chain staking is enabled, each compute/vision/MPC/daemon
node must meet min_stake before registration is accepted.
Continuous enforcement: stake eligibility is re-checked during live operation. Nodes that fall below eligibility are excluded from discovery and health views until re-staked.
Privacy note: If you run public-facing UNFED nodes and do not want your home/office IP exposed, consider operating behind a VPN, proxy, or hosted relay endpoint. Your node address can be discovered by other participants through registry/network activity.
The web UI for sending prompts and monitoring the network.
python -m web.server \
--port 8080 \
--registry localhost:50050
Open http://localhost:8080 in your browser. You can type prompts,
attach images (for multimodal models), and watch tokens stream in real-time.
The dashboard shows per-request cost based on the cluster's token pricing.
Security defaults: the dashboard now binds to
127.0.0.1 by default (not 0.0.0.0), demo auth is
disabled by default, and wallet auth is expected for chat/faucet flows.
Faucet default: faucet is disabled unless
UNFED_FAUCET_ENABLED=1. When enabled, it requires an authenticated
wallet session by default (UNFED_FAUCET_REQUIRE_AUTH=1).
Use Go/No-Go checks before exposing services.
# Web service checks
python -m scripts.testnet_preflight web --host 127.0.0.1
# Public node checks (TLS required for public advertise)
python -m scripts.testnet_preflight node \
--advertise 203.0.113.42:50051 \
--tls-cert /path/to/server.crt \
--tls-key /path/to/server.key
# Runtime checks against running web/registry stack
python -m scripts.testnet_preflight runtime --web-url http://127.0.0.1:8080
# Optional one-command profile check
./scripts/run_public_testnet_checklist.sh
If any check fails, treat the result as NO-GO and fix the reported issue before rollout.
Output privacy modes: use he_compute_mode with
off, decode_client_sample, or
full_output_2pc. The legacy server_sample mode is retired.
Vision MPC validation: run the lightweight pytest path by default, then opt into heavy E2E when ready.
# Default: unit-level vision checks (pytest-friendly)
python -m pytest tests/test_vision.py -q
# Heavy E2E vision network check (requires model/shards and more resources)
RUN_VISION_E2E=1 python -m pytest tests/test_vision.py -q
What happens when nodes cheat, and why staking is required for operators.
Detection and dispute intake are handled by registry-native adjudication and evidence-bound report paths.
Fraud Proof Details →min_stake is excluded until re-stakedThis is the core incentive design: honest compute remains profitable, cheating becomes expensive.
Staking Model → Slashing Flow →
Operator checklist: before public rollout, confirm your
cluster_config.json sets sensible values for
default_min_stake, default_slash_fraction,
challenge_window_seconds, and
he_dispute_rollout_stage.
After startup, verify readiness:
python -m client.client --list-models --registry localhost:50050
Expected: your target model shows Status: READY before serving users.
For local testing with Foundry's Anvil.
curl -L https://foundry.paradigm.xyz | bash
foundryup
anvil --block-time 2
This starts a local Ethereum node with pre-funded accounts.
# Deploy ERC-20 token
forge create contracts/UnfedToken.sol:UnfedToken \
--rpc-url http://localhost:8545 \
--private-key $DEPLOYER_KEY
# Deploy escrow contract
forge create contracts/UnfedEscrow.sol:UnfedEscrow \
--rpc-url http://localhost:8545 \
--private-key $DEPLOYER_KEY \
--constructor-args $TOKEN_ADDRESS $OPERATOR_ADDRESS
# Transfer tokens to a node address
cast send $TOKEN_ADDRESS \
"transfer(address,uint256)" $NODE_ADDRESS 200000000000000000000 \
--rpc-url http://localhost:8545 --private-key $DEPLOYER_KEY
# Approve escrow to spend tokens
cast send $TOKEN_ADDRESS \
"approve(address,uint256)" $ESCROW_ADDRESS 200000000000000000000 \
--rpc-url http://localhost:8545 --private-key $NODE_KEY
# Stake
cast send $ESCROW_ADDRESS \
"stake(uint256)" 200000000000000000000 \
--rpc-url http://localhost:8545 --private-key $NODE_KEY
Convenience: The start_smolvlm_staked.sh script
automates the entire process: Anvil startup, contract deployment, token
distribution, staking, and launching all nodes. Check the repository for
the full script.
Understand how sharding, MPC, and onion routing work together.
Architecture →Share chains, verification tickets, fraud proofs, and settlements.
Protocol →