- 1. Requirements
- 2. Setup
- 3. Create a Wallet
- 4. Run the Validator
- 5. Options
- 5.1. Common Options
--axon.port INTEGER--sma.low.days INTEGER--sma.high.days INTEGER--softmax.low.beta FLOAT--softmax.high.beta FLOAT--logging.debug--logging.info--logging.trace--netuid INTEGER--neuron.axon_off BOOLEAN--neuron.device TEXT--neuron.disable_set_weights BOOLEAN--neuron.dont_save_events BOOLEAN--neuron.epoch_length INTEGER--neuron.events_retention_size TEXT--neuron.name TEXT--neuron.sample_size INTEGER--neuron.timeout INTEGER--neuron.nprocs INTEGER--neuron.vpermit_tao_limit INTEGER--wallet.hotkey TEXT--wallet.name TEXT
- 5.2. Logging Options
- 5.1. Common Options
- 6. Appendix
Step 1: Clone the repository
git clone https://github.com/synthdataco/synth-subnet.gitStep 2: Change directory to the project root
cd ./synth-subnetStep 3: Add the required repositories
sudo add-apt-repository ppa:deadsnakes/ppa
⚠️ NOTE: The deadsnakes repository, while unofficial, it is hugely popular and used by many Python projects.
Step 4: Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shStep 5: Install the dependencies
sudo apt update && \
sudo apt install nodejs npm python3.11 pkg-configStep 6: Install PM2
sudo npm install pm2 -gStep 7: Install the Python environment
sudo apt install python3.11-venvStep 8: Create a new Python environment
python3.11 -m venv bt_venvStep 9: Activate and switch to the newly created Python virtual environment
source bt_venv/bin/activateThis should activate the bt_venv environment and you should see the command line prefixed with (bt_venv).
Step 10: Install local Python dependencies
With the Python virtual environment active, install the Python dependencies:
pip install -r requirements.txt💡 TIP: For a more extensive list of the Bittensor CLI commands see here.
Step 1: Activate the Python virtual environment
If you haven't already, ensure you are running from the Python virtual environment:
source bt_venv/bin/activateStep 2: Create the cold/hot wallets
btcli wallet create \
--wallet.name validator \
--wallet.hotkey default🚨 WARNING: You must ensure your wallets have enough TAO (0.1 should be sufficient) to be start mining. For testnet, you can use the
btcli wallet faucet.
Step 3: Register wallet
Acquire a slot on the Bittensor subnet by registering the wallet:
btcli subnet register \
--wallet.name validator \
--wallet.hotkey default \
--netuid 50if you want to try it on testnet first, run the following command:
btcli subnet register \
--wallet.name validator \
--wallet.hotkey default \
--network test \
--netuid 247btcli root register --wallet.name validator --wallet.hotkey default- Stake:
btcli stake add \
--wallet.name validator \
--wallet.hotkey default \
--netuid 50for testnet:
btcli stake add \
--wallet.name validator \
--wallet.hotkey default \
--network test \
--netuid 247Step 4: Verify wallet registration (optional)
Check the wallet has been registered:
btcli wallet overview \
--wallet.name validator \
--wallet.hotkey defaultYou can also check the network metagraph:
btcli subnet metagraph \
--netuid 50for testnet it's:
btcli subnet metagraph \
--network test \
--netuid 247Step 1: Database setup
- Create a postgres database with the name "synth"
- Rename the ".env.example" in the root of the repo to ".env"
- Update the
.envfile with your database credentials.
Step 2: Activate the Python virtual environment
source bt_venv/bin/activateStep 3: Run database migrations
alembic upgrade headStep 4: Start PM2 with the validator config
pm2 start validator.config.jsfor testnet use:
pm2 start validator.test.config.jsStep 5: Check the validator is running (optional)
pm2 list💡 NOTE: The validator queries miners in parallel via a multiprocess dendrite. The number of worker processes is controlled by
--neuron.nprocs(default2). The1hHFT competition sends prompts every ~10 min, so under-sized hosts can miss cycle deadlines — size--neuron.nprocsto roughly match the CPU cores available on the host.
The external port for the Axon component. This port is used to communicate to other neurons.
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--axon.port 8091",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --axon.port 8091for testnet it's:
pm2 start validator.test.config.js -- --axon.port 8091The window for the simple moving average (SMA) of the validator scores for the 24h prompt.
Default: 10
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--sma.low.days 10",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --sma.low.days 10The window for the simple moving average (SMA) of the validator scores for the 1h prompt.
Default: 3
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--sma.high.days 3",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --sma.high.days 3Negative beta to give higher weight to lower scores for the 24h prompt
Default: -0.1
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--softmax.low.beta -0.1",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --softmax.low.beta -0.1Negative beta to give higher weight to lower scores for the 1h prompt
Default: -0.2
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--softmax.high.beta -0.2",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --softmax.high.beta -0.2Turn on bittensor debugging information.
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--logging.debug",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --logging.debugTurn on bittensor info level information.
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--logging.info",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --logging.infoTurn on bittensor trace level information.
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--logging.trace",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --logging.traceThe netuid (network unique identifier) of the subnet within the root network, (e.g. 247).
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--netuid 247",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --netuid 247This will switch off the Axon component.
Default: false
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--neuron.axon_off true",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --neuron.axon_off trueThe name of the device to run on.
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--neuron.device cuda",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --neuron.device cudaWhether events are saved to a log file.
Default: false
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--neuron.dont_save_events true",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --neuron.dont_save_events trueDisables setting weights.
Default: false
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--neuron.disable_set_weights true",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --neuron.disable_set_weights trueThe default epoch length (how often we set weights, measured in 12 second blocks), (e.g. 100).
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--neuron.epoch_length 100",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --neuron.epoch_length 100The events retention size.
Default: 2147483648 (2GB)
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--neuron.events_retention_size 2147483648",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --neuron.events_retention_size 2147483648Trials for this neuron go in neuron.root / (wallet_cold - wallet_hot) / neuron.name.
Default: validator
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--neuron.name validator",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --neuron.name validatorThe number of validators to query in a single step.
Default: 50
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--neuron.sample_size 50",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --neuron.sample_size 50The maximum timeout in seconds of the validator neuron response, (e.g. 120).
Default: -
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--neuron.timeout 120",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --neuron.timeout 120The number of processes to run for the validator dendrite, (e.g. 2).
Default: 2
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--neuron.nprocs 2",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --neuron.nprocs 2The maximum number of TAO allowed that is allowed for the validator to process validator response, (e.g. 1000).
Default: 4096
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--neuron.vpermit_tao_limit 1000",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --neuron.vpermit_tao_limit 1000The hotkey of the wallet.
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--wallet.hotkey default",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --wallet.hotkey defaultThe name of the wallet to use.
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--wallet.name validator",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --wallet.name validatorString to set the GCP log ID prefix.
Example:
// validator.config.js
module.exports = {
apps: [
{
name: "validator",
interpreter: "python3",
script: "./neurons/validator.py",
args: "--gcp.log_id_prefix my_validator_name",
env: {
PYTHONPATH: ".",
},
},
],
};Alternatively, you can add the args directly to the command:
pm2 start validator.config.js -- --gcp.log_id_prefix my_validator_namefor testnet it's:
pm2 start validator.test.config.js -- --gcp.log_id_prefix my_validator_name| Command | Description |
|---|---|
pm2 stop validator |
Stops the validator. |
pm2 logs validator --lines 100 |
View the logs of the validator. |
You can run the validator with Docker and docker compose.
- Run this command:
cp .env.validator .env.validator.local
- Optionally edit "POSTGRES_PASSWORD" in
.env.validator.localfile. Don't change "POSTGRES_DB" - Optionally edit
entrypoint-validator.shfile, especiallylog_id_prefixif you want to forward the log to a GCP Log Bucket. For this you need the credential file and environment variable GOOGLE_APPLICATION_CREDENTIALS set to the path of this file - Install docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
- Setup your bittensor wallet
- Start:
docker compose up --build --remove-orphans --force-recreate -d - Update with the same command
- Read the logs:
docker compose logs -f
- Enter into the postgres container:
docker exec -it postgres bash - Enter into psql:
psql -U postgres - List databases:
\l. You should see "synth" database - Connect to database:
\c synth
- Check the validator requests:
select * from validator_requests order by start_time desc limit 500; - Check the miner predictions:
select mp.format_validation, vr.start_time, miners.miner_uid, process_time
from miner_predictions mp
join validator_requests vr on mp.validator_requests_id = vr.id
join miners on miners.id = mp.miner_id
order by start_time desc
limit 500;
- Check the miner scores:
SELECT
MS.ID,
MP.VALIDATOR_REQUESTS_ID,
MS.MINER_PREDICTIONS_ID,
VR.START_TIME,
VR.ASSET,
MS.SCORED_TIME,
MINERS.MINER_UID,
(MS.SCORE_DETAILS_V3 -> 'total_crps')::FLOAT AS CSRP,
MS.PROMPT_SCORE_V3
FROM
MINER_SCORES MS
JOIN MINER_PREDICTIONS MP ON MP.ID = MS.MINER_PREDICTIONS_ID
JOIN MINERS ON MINERS.ID = MP.MINER_ID
JOIN VALIDATOR_REQUESTS VR ON VR.ID = MP.VALIDATOR_REQUESTS_ID
WHERE
MS.SCORED_TIME > NOW()::DATE - 10
ORDER BY
MS.ID DESC;
- Check the predictions table size:
SELECT pg_size_pretty(pg_total_relation_size('miner_predictions')) as size; - /!\ Delete old predictions
delete from miner_predictions
using validator_requests
where miner_predictions.validator_requests_id = validator_requests.id
and validator_requests.start_time < now()::DATE - 20;