docs: keep the fleet's shape out of prose
Site names, host assignments and hardware inventories were scattered through readme.md, CLAUDE.md and a unit-file comment. They belong in the deploy matrices — the single source of infra truth — and nowhere else. readme.md now describes roles and measured hardware classes rather than which box is where; the GPU-contention section is written as a check to perform rather than a named host. CLAUDE.md gains a standing rule so this does not creep back.
This commit is contained in:
@@ -2,11 +2,12 @@ name: deploy
|
||||
# Deploy — or validate — Quantus Planck nodes and their external GPU miners.
|
||||
#
|
||||
# Topology (the workflow is the source of infra truth,
|
||||
# ~/git/architecture/deployment-gitea-actions.md):
|
||||
# ~/git/architecture/deployment-gitea-actions.md — hosts belong here, and only
|
||||
# here; see readme.md "Scope"):
|
||||
#
|
||||
# bob.hanzalova.internal quantus-node consensus, P2P, rewards
|
||||
# ▲ QUIC/9833 (mesh only, rich-rule scoped to the miner host)
|
||||
# benjy.hanzalova.internal quantus-miner 1× RTX 4090
|
||||
# quantus-node consensus, P2P, rewards
|
||||
# ▲ QUIC/9833 (mesh only, rich-rule scoped to that node's miners)
|
||||
# quantus-miner GPU search
|
||||
#
|
||||
# The node and the miner are separate processes on separate hosts by design: the
|
||||
# node is disk+network bound and belongs on an always-on box, the miner is pure
|
||||
@@ -121,7 +122,6 @@ jobs:
|
||||
# (doc/wormhole-rewards.md §6):
|
||||
# quantus-node key quantus --scheme wormhole --words < mnemonic.txt
|
||||
- host: bob.hanzalova.internal
|
||||
site: plovdiv
|
||||
inner_hash: "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||
miners: benjy.hanzalova.internal # space-separated if more than one
|
||||
# Second site, for decentralisation. Uncomment when provisioned, and
|
||||
@@ -130,12 +130,11 @@ jobs:
|
||||
# the point of running them separately (doc/wormhole-rewards.md §5).
|
||||
#
|
||||
# NOTE: a node with no miners authors nothing, because
|
||||
# --miner-listen-port disables built-in mining. If Kyustendil is meant
|
||||
# to be a plain relaying full node (the readme's suggestion), it needs
|
||||
# a unit WITHOUT --validator/--miner-listen-port, not this one — and
|
||||
# then it needs no inner_hash at all.
|
||||
# - host: gramathea.kosherinata.internal
|
||||
# site: kyustendil
|
||||
# --miner-listen-port disables built-in mining. A node intended purely
|
||||
# to relay and validate needs a unit WITHOUT
|
||||
# --validator/--miner-listen-port, not this one — and then it needs no
|
||||
# inner_hash at all.
|
||||
# - host: <second-node>.internal
|
||||
# inner_hash: "0x..."
|
||||
# miners: ""
|
||||
steps:
|
||||
@@ -268,7 +267,7 @@ jobs:
|
||||
run() { ssh $SSHOPTS gitea_ci@"${{ matrix.host }}" "$@"; }
|
||||
fail=0
|
||||
|
||||
echo "--- unit (${{ matrix.site }}) ---"
|
||||
echo "--- unit (${{ matrix.host }}) ---"
|
||||
run systemctl is-active quantus-node.service
|
||||
|
||||
echo "--- version ---"
|
||||
|
||||
@@ -83,8 +83,17 @@ node takes a preimage rather than an address, what publishing it does and does
|
||||
not expose, and why the seed-phrase derivation step is a design flaw rather than
|
||||
an operator error. Read it before changing anything about reward configuration.
|
||||
|
||||
## Before enabling the miner on benjy
|
||||
## Before enabling a miner on any host
|
||||
|
||||
`benjy` already runs helexa `neuron` on `:13131` against the same RTX 4090. The
|
||||
miner will saturate that GPU. `readme.md` documents the options; the deploy
|
||||
deliberately does not arbitrate. This is an open decision, not an oversight.
|
||||
A miner host may already be serving helexa `neuron` from the same GPU. The miner
|
||||
will saturate it. `readme.md` documents the options; the deploy deliberately
|
||||
does not arbitrate. This is an open decision, not an oversight.
|
||||
|
||||
## Keep the fleet's shape in the workflow
|
||||
|
||||
Host assignments, hardware inventories, site or geographic names, ISPs and
|
||||
addressing belong in the `deploy-node` / `deploy-miner` matrices in
|
||||
`.gitea/workflows/deploy.yaml` — the single source of infra truth — and nowhere
|
||||
else. Do not restate them in `readme.md`, `CLAUDE.md`, `doc/`, or unit-file
|
||||
comments, even as helpful context. Prose should describe roles and measured
|
||||
hardware classes, never which box is where.
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
# there is no tuning knob here worth more than the GPU power limit — which is a
|
||||
# host-level concern (nvidia-smi -pl), not a unit-file one.
|
||||
#
|
||||
# --cpu-workers 0 is deliberate: benjy's i9-13900KF contributes ~3.9 MH/s next
|
||||
# to the 4090's ~183 MH/s, for a couple hundred watts. Measured, not assumed.
|
||||
# --cpu-workers 0 is deliberate: a current-gen desktop CPU contributes ~4 MH/s
|
||||
# next to a 4090's ~183 MH/s, for a couple hundred watts. Measured, not assumed.
|
||||
|
||||
[Unit]
|
||||
Description=Quantus external miner (GPU)
|
||||
|
||||
@@ -3,12 +3,18 @@
|
||||
Deployment for a [Quantus Network](https://quantus.com) Planck node and its
|
||||
external GPU miner.
|
||||
|
||||
Two components, two hosts:
|
||||
Two components:
|
||||
|
||||
| Component | Host | Role |
|
||||
| --- | --- | --- |
|
||||
| `quantus-node` | `bob.hanzalova.internal` | consensus, P2P, reward address. Disk + network bound. |
|
||||
| `quantus-miner` | `benjy.hanzalova.internal` | Poseidon2-over-Goldilocks search on 1× RTX 4090. Pure GPU compute. |
|
||||
| Component | Role |
|
||||
| --- | --- |
|
||||
| `quantus-node` | consensus, P2P, reward address. Disk + network bound. |
|
||||
| `quantus-miner` | Poseidon2-over-Goldilocks search. Pure GPU compute. |
|
||||
|
||||
**Scope:** which hosts run what lives in the `deploy-node` / `deploy-miner`
|
||||
matrices in `.gitea/workflows/deploy.yaml` and nowhere else — that is the
|
||||
convention (`deployment-gitea-actions.md`) and it keeps the fleet's shape in one
|
||||
place instead of scattered through prose. Don't restate host assignments,
|
||||
hardware inventories, sites or addressing in this file.
|
||||
|
||||
They are split deliberately. Setting `--miner-listen-port` on the node
|
||||
**disables its built-in CPU mining**, so the node authors nothing unless an
|
||||
@@ -29,16 +35,17 @@ in registers, and there is no memory hardness at all. Measured on this fleet:
|
||||
|
||||
| Hardware | Hashrate | Power | Efficiency |
|
||||
| --- | --- | --- | --- |
|
||||
| RTX 5090 (`beast`, ×2) | 368 MH/s each | 600 W | 0.60 MH/s/W |
|
||||
| RTX 5090 | 368 MH/s | 600 W | 0.60 MH/s/W |
|
||||
| RTX 5090 @ 400 W floor | 281 MH/s | 400 W | 0.70 MH/s/W |
|
||||
| RTX 4090 (`benjy`) | 183 MH/s | 450 W | 0.41 MH/s/W |
|
||||
| Ryzen 9 9950X3D, 32t | 4.15 MH/s | — | — |
|
||||
| Xeon E5-2620 v3, 12t (`bob`) | 0.50 MH/s | — | — |
|
||||
| RTX 4090 | 183 MH/s | 450 W | 0.41 MH/s/W |
|
||||
| current-gen desktop CPU, 32t | ~4 MH/s | — | — |
|
||||
| older server CPU, 12t | ~0.5 MH/s | — | — |
|
||||
|
||||
A single 5090 at its minimum power limit out-hashes every CPU in the fleet
|
||||
combined by roughly 24×. CPU mining is therefore disabled everywhere
|
||||
(`--cpu-workers 0`), including on the GPU hosts, where it would add ~1% hashrate
|
||||
for a couple hundred watts. The old Xeons are node-capable and mining-worthless.
|
||||
Measured on representative hardware, not estimated. A single 5090 at its minimum
|
||||
power limit out-hashes a couple of dozen server CPUs combined. CPU mining is
|
||||
therefore disabled everywhere (`--cpu-workers 0`), including on GPU hosts, where
|
||||
it would add ~1% hashrate for a couple hundred watts. Older server CPUs are
|
||||
node-capable and mining-worthless.
|
||||
|
||||
GPU/CPU parity is verified upstream (`engine-gpu`'s `gpu_cpu_parity` example,
|
||||
25/25 jobs) — the GPU is doing real work, not advancing a lying counter.
|
||||
@@ -145,24 +152,23 @@ attached, both look perfectly healthy to systemd. Hence the counter check.
|
||||
Upgrades are deliberate — bump `NODE_VERSION` / `MINER_VERSION` in the workflow.
|
||||
There is no auto-update on a validator on purpose.
|
||||
|
||||
## Known conflict: helexa on `benjy` ⚠️
|
||||
## Known conflict: GPU contention with helexa ⚠️
|
||||
|
||||
`benjy` already runs **helexa `neuron`** on `:13131` (`architecture/generic.md`
|
||||
§11, `inference.md`), serving inference from the same RTX 4090 this miner will
|
||||
saturate. They will contend directly: the miner drives the GPU to ~95%
|
||||
utilisation and ~450 W continuously, which will make inference latency on benjy
|
||||
by turns awful and unpredictable.
|
||||
A miner host may already be running helexa `neuron` against the same GPU
|
||||
(`architecture/generic.md` §11, `inference.md`). They contend directly: the miner
|
||||
drives the GPU to ~95% utilisation and near its power limit continuously, which
|
||||
makes inference latency on that host by turns awful and unpredictable.
|
||||
|
||||
Nothing here resolves that, and the deploy does not try to arbitrate. Options,
|
||||
in rough order of preference:
|
||||
|
||||
1. Move mining to `beast` (2× 5090, and 4× the hashrate) and leave benjy to
|
||||
inference. Requires checking what beast's neuron is doing first.
|
||||
1. Put mining on a host that is not serving inference.
|
||||
2. Make the miner yield — `--gpu-throttle-ms`, or an `ExecCondition` that
|
||||
refuses to start while a model is loaded.
|
||||
3. Accept the contention on benjy and treat inference there as best-effort.
|
||||
3. Accept the contention and treat inference on that host as best-effort.
|
||||
|
||||
Decide before enabling `quantus-miner.service` on benjy, not after.
|
||||
Check what a candidate miner host is already serving before enabling
|
||||
`quantus-miner.service` on it, not after.
|
||||
|
||||
## Deviations from house convention
|
||||
|
||||
|
||||
Reference in New Issue
Block a user