feat(us-026): smart model assignment via demand×coverage scoring

/v1/network/assign now scores models by (demand_rpm + 1) × (coverage_deficit + 0.01)
so high-traffic, under-covered models are preferred when assigning new nodes.
Response includes price_per_token: 0.0 (reserved for future pricing protocol).
--memory MB flag added to node CLI to override autodetected VRAM budget for
shard assignment without changing hardware detection for inference.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Dobromir Popov
2026-06-30 13:42:43 +03:00
parent d9110b623b
commit 27818df654
3 changed files with 33 additions and 6 deletions

View File

@@ -27,6 +27,7 @@ def _run_node(cfg: dict) -> None:
cache_dir=Path(cfg["download_dir"]) if cfg.get("download_dir") else None,
host=cfg.get("host", "0.0.0.0"),
route_timeout=float(cfg.get("route_timeout", 30.0)),
vram_mb_override=cfg.get("vram_mb_override"),
)
except Exception as exc:
print(f"\nERROR: {exc}", file=sys.stderr, flush=True)
@@ -89,6 +90,8 @@ def _cmd_default(args) -> int:
overrides["host"] = args.host
if args.route_timeout != 30.0:
overrides["route_timeout"] = args.route_timeout
if getattr(args, "memory", None) is not None:
overrides["vram_mb_override"] = args.memory
if overrides:
cfg = merge_cli_overrides(cfg, **overrides)
@@ -177,6 +180,7 @@ def _cmd_start(args) -> int:
host=cfg["host"],
advertise_host=getattr(args, "advertise_host", None),
route_timeout=getattr(args, "route_timeout", 30.0),
vram_mb_override=getattr(args, "memory", None),
)
except Exception as exc:
print(f"ERROR: {exc}", file=sys.stderr, flush=True)
@@ -218,6 +222,8 @@ def main() -> None:
parser.add_argument("--host", metavar="ADDR", help="Interface to bind (default 0.0.0.0)")
parser.add_argument("--route-timeout", type=float, metavar="SEC", default=30.0,
help="Seconds to wait for tracker route lookup (default 30)")
parser.add_argument("--memory", type=int, metavar="MB", default=None,
help="Override autodetected VRAM/RAM budget in MB used for shard assignment")
parser.add_argument("--no-tui", action="store_true", help="Plain-text output (no rich dashboard)")
parser.add_argument("--compact", action="store_true", help="Single-line status output")
parser.add_argument("--reset-config", action="store_true", help="Re-run wizard even if config exists")
@@ -248,6 +254,8 @@ def main() -> None:
start_cmd.add_argument("--download-dir")
start_cmd.add_argument("--route-timeout", type=float, default=30.0,
help="Seconds to wait for tracker route lookup (default 30)")
start_cmd.add_argument("--memory", type=int, default=None, metavar="MB",
help="Override autodetected VRAM/RAM budget in MB used for shard assignment")
args = parser.parse_args()

View File

@@ -141,6 +141,7 @@ def run_startup(
advertise_host: str | None = None,
contracts: Any | None = None,
route_timeout: float = 30.0,
vram_mb_override: int | None = None,
) -> StubNodeServer | TorchNodeServer:
"""Execute the full startup sequence and return a running node server.
@@ -177,7 +178,10 @@ def run_startup(
gpu_name: str | None = hw.get("gpu_name")
vram_mb: int = hw.get("vram_mb", 0)
if device == "cpu":
if vram_mb_override is not None:
vram_mb = vram_mb_override
print(f" Memory budget overridden to {vram_mb} MB via --memory", flush=True)
elif device == "cpu":
print(" WARNING: No CUDA GPU detected — running in CPU mode", flush=True)
else:
print(f" GPU: {gpu_name} ({vram_mb} MB VRAM)", flush=True)