[verified] feat: complete Ralph task workstreams
This commit is contained in:
@@ -14,9 +14,19 @@ import urllib.request
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
from .admission import (
|
||||
AdmissionRequirement,
|
||||
CapabilityContext,
|
||||
CapabilityValidator,
|
||||
admit,
|
||||
probe_capability,
|
||||
)
|
||||
from .capability import CapabilityReport
|
||||
from .doctor import DoctorSelection
|
||||
from .downloader import compute_shard_checksum, download_shard
|
||||
from .hardware import detect_hardware, benchmark_throughput_checked, with_forced_cpu
|
||||
from .model_catalog import model_metadata_for
|
||||
from .recipe_manifest import DEFAULT_RECIPE_ID, Recipe, RecipeManifest, load_recipe_manifest
|
||||
from .relay_bridge import RelayHttpBridge, peer_id_from_wallet
|
||||
from .server import StubNodeServer
|
||||
from .torch_server import TorchNodeServer
|
||||
@@ -646,6 +656,68 @@ def _tracker_http_error_message(exc: urllib.error.HTTPError) -> str:
|
||||
return f"Tracker rejected shard assignment (HTTP {exc.code}): {detail}"
|
||||
|
||||
|
||||
def _resolve_recipe(recipe_id: str | None) -> tuple[RecipeManifest, Recipe]:
|
||||
"""The recipe this node will serve with — resolved before any weights load."""
|
||||
manifest = load_recipe_manifest()
|
||||
return manifest, manifest.require(recipe_id or DEFAULT_RECIPE_ID)
|
||||
|
||||
|
||||
def _capability_device(backend: Any, detected_device: str) -> str:
|
||||
"""The device the shard actually landed on, or the one this node detected."""
|
||||
device = getattr(backend, "device", None)
|
||||
if device is None:
|
||||
return detected_device
|
||||
return str(getattr(device, "type", device))
|
||||
|
||||
|
||||
def _admit_capability(
|
||||
node: Any,
|
||||
*,
|
||||
model_id: str,
|
||||
shard_start: int,
|
||||
shard_end: int,
|
||||
quantization: str,
|
||||
cache_dir: Path | None,
|
||||
force_cpu: bool,
|
||||
detected_device: str,
|
||||
manifest: RecipeManifest,
|
||||
recipe: Recipe,
|
||||
validator: CapabilityValidator | None,
|
||||
) -> CapabilityReport:
|
||||
"""Prove this node can serve the selection, or refuse to advertise it.
|
||||
|
||||
Runs on the loaded backend before the server starts listening, so a node that
|
||||
cannot execute its shard never reaches a routable endpoint, never registers,
|
||||
and never accepts paid work. `CapabilityAdmissionError` propagates to the CLI,
|
||||
which exits non-zero.
|
||||
"""
|
||||
backend = getattr(node, "backend", None)
|
||||
context = CapabilityContext(
|
||||
backend=backend,
|
||||
selection=DoctorSelection(
|
||||
model_id=model_id,
|
||||
shard_start=shard_start,
|
||||
shard_end=shard_end,
|
||||
quantization=quantization,
|
||||
cache_dir=cache_dir,
|
||||
force_cpu=force_cpu,
|
||||
),
|
||||
recipe=recipe,
|
||||
manifest=manifest,
|
||||
device=_capability_device(backend, detected_device),
|
||||
)
|
||||
print(
|
||||
f"Validating capability — {model_id} layers {shard_start}–{shard_end}, "
|
||||
f"recipe {recipe.id}...",
|
||||
flush=True,
|
||||
)
|
||||
report = (validator or probe_capability)(context)
|
||||
setattr(node, "capability_report", report) # local evidence, passed or failed
|
||||
admit(AdmissionRequirement.for_context(context), report)
|
||||
print(f" Capability proven on {context.device} ({report.duration_ms} ms)", flush=True)
|
||||
return report
|
||||
|
||||
|
||||
def run_startup(
|
||||
tracker_url: str,
|
||||
port: int = 0,
|
||||
@@ -668,6 +740,8 @@ def run_startup(
|
||||
torch_interop_threads: int | None = None,
|
||||
node_name: str | None = None,
|
||||
force_cpu: bool = False,
|
||||
recipe_id: str | None = None,
|
||||
capability_validator: CapabilityValidator | None = None,
|
||||
) -> StubNodeServer | TorchNodeServer:
|
||||
"""Execute the full startup sequence and return a running node server.
|
||||
|
||||
@@ -676,13 +750,18 @@ def run_startup(
|
||||
2. Load or generate Solana wallet keypair
|
||||
3. Query tracker for optimal shard assignment
|
||||
4. Download (or stub) the assigned shard from peers, then HuggingFace
|
||||
5. Start local HTTP server
|
||||
6. Register with tracker
|
||||
5. Prove the loaded shard runs — a failure here exits before step 6
|
||||
6. Start local HTTP server and register with tracker
|
||||
|
||||
`capability_validator` is how step 5 is proven. It defaults to a real forward
|
||||
through the loaded shard; only tests replace it, and only with the explicit
|
||||
seams in `meshnet_node.testing` — there is no bypass a deployment can reach.
|
||||
|
||||
Prints a compact status summary on completion.
|
||||
"""
|
||||
|
||||
tracker_url = tracker_url.rstrip("/")
|
||||
manifest, recipe = _resolve_recipe(recipe_id)
|
||||
relay_url = _discover_relay_url(tracker_url)
|
||||
display_fields = _registration_display_fields(node_name)
|
||||
if max_loaded_shards < 1:
|
||||
@@ -874,6 +953,20 @@ def run_startup(
|
||||
debug=debug,
|
||||
max_loaded_shards=max_loaded_shards,
|
||||
force_cpu=force_cpu,
|
||||
recipe_params=recipe.params,
|
||||
)
|
||||
capability_report = _admit_capability(
|
||||
node,
|
||||
model_id=model_id,
|
||||
shard_start=shard_start,
|
||||
shard_end=shard_end,
|
||||
quantization=quantization,
|
||||
cache_dir=cache_dir,
|
||||
force_cpu=force_cpu,
|
||||
detected_device=device,
|
||||
manifest=manifest,
|
||||
recipe=recipe,
|
||||
validator=capability_validator,
|
||||
)
|
||||
_node_start_time = time.monotonic()
|
||||
actual_port = node.start()
|
||||
@@ -910,6 +1003,11 @@ def run_startup(
|
||||
"tracker_mode": (shard_start == 0),
|
||||
"managed_assignment": not user_pinned_shard,
|
||||
"model_metadata": model_metadata_for(model_id, total_layers, cache_dir=cache_dir),
|
||||
"capability_report": capability_report.to_dict(),
|
||||
# Declared independently of the proof: the tracker checks that the
|
||||
# recipe this node says it serves with is the one the proof ran.
|
||||
"recipe_id": recipe.id,
|
||||
"recipe_version": recipe.version,
|
||||
"downloaded_models": (
|
||||
_downloaded_model_inventory(
|
||||
model_id.split("/")[-1],
|
||||
@@ -1030,6 +1128,20 @@ def run_startup(
|
||||
debug=debug,
|
||||
max_loaded_shards=max_loaded_shards,
|
||||
force_cpu=force_cpu,
|
||||
recipe_params=recipe.params,
|
||||
)
|
||||
capability_report = _admit_capability(
|
||||
node,
|
||||
model_id=assigned_hf_repo,
|
||||
shard_start=assigned_shard_start,
|
||||
shard_end=assigned_shard_end,
|
||||
quantization=quantization,
|
||||
cache_dir=cache_dir,
|
||||
force_cpu=force_cpu,
|
||||
detected_device=device,
|
||||
manifest=manifest,
|
||||
recipe=recipe,
|
||||
validator=capability_validator,
|
||||
)
|
||||
_node_start_time = time.monotonic()
|
||||
actual_port = node.start()
|
||||
@@ -1062,6 +1174,11 @@ def run_startup(
|
||||
"tracker_mode": (assigned_shard_start == 0),
|
||||
"managed_assignment": True,
|
||||
"model_metadata": model_metadata_for(assigned_hf_repo, assigned_num_layers, cache_dir=cache_dir),
|
||||
"capability_report": capability_report.to_dict(),
|
||||
# Declared independently of the proof: the tracker checks that the
|
||||
# recipe this node says it serves with is the one the proof ran.
|
||||
"recipe_id": recipe.id,
|
||||
"recipe_version": recipe.version,
|
||||
"downloaded_models": (
|
||||
_downloaded_model_inventory(
|
||||
assigned_hf_repo.split("/")[-1],
|
||||
@@ -1212,6 +1329,20 @@ def run_startup(
|
||||
debug=debug,
|
||||
max_loaded_shards=max_loaded_shards,
|
||||
force_cpu=force_cpu,
|
||||
recipe_params=recipe.params,
|
||||
)
|
||||
capability_report = _admit_capability(
|
||||
node,
|
||||
model_id=hf_repo,
|
||||
shard_start=shard_start,
|
||||
shard_end=shard_end,
|
||||
quantization=quantization,
|
||||
cache_dir=shard_path,
|
||||
force_cpu=force_cpu,
|
||||
detected_device=device,
|
||||
manifest=manifest,
|
||||
recipe=recipe,
|
||||
validator=capability_validator,
|
||||
)
|
||||
actual_port = node.start()
|
||||
total_layers = getattr(getattr(node, "backend", None), "total_layers", None) or assigned_total_layers
|
||||
@@ -1247,6 +1378,11 @@ def run_startup(
|
||||
"tracker_mode": (shard_start == 0),
|
||||
"managed_assignment": not user_pinned_shard,
|
||||
"model_metadata": model_metadata_for(hf_repo, total_layers, cache_dir=shard_path),
|
||||
"capability_report": capability_report.to_dict(),
|
||||
# Declared independently of the proof: the tracker checks that the
|
||||
# recipe this node says it serves with is the one the proof ran.
|
||||
"recipe_id": recipe.id,
|
||||
"recipe_version": recipe.version,
|
||||
**registration_capabilities,
|
||||
**relay_fields,
|
||||
**display_fields,
|
||||
@@ -1282,6 +1418,19 @@ def run_startup(
|
||||
model=assigned_model,
|
||||
shard_path=shard_path,
|
||||
)
|
||||
capability_report = _admit_capability(
|
||||
node,
|
||||
model_id=assigned_model,
|
||||
shard_start=shard_start,
|
||||
shard_end=shard_end,
|
||||
quantization=quantization,
|
||||
cache_dir=shard_path,
|
||||
force_cpu=force_cpu,
|
||||
detected_device=device,
|
||||
manifest=manifest,
|
||||
recipe=recipe,
|
||||
validator=capability_validator,
|
||||
)
|
||||
actual_port = node.start()
|
||||
public_host = advertise_host or (socket.getfqdn() if host == "0.0.0.0" else host)
|
||||
endpoint = f"http://{public_host}:{actual_port}"
|
||||
@@ -1304,6 +1453,11 @@ def run_startup(
|
||||
"shard_start": shard_start,
|
||||
"shard_end": shard_end,
|
||||
"shard_checksum": shard_checksum,
|
||||
"capability_report": capability_report.to_dict(),
|
||||
# Declared independently of the proof: the tracker checks that the
|
||||
# recipe this node says it serves with is the one the proof ran.
|
||||
"recipe_id": recipe.id,
|
||||
"recipe_version": recipe.version,
|
||||
"downloaded_models": downloaded_models,
|
||||
"hardware_profile": hw,
|
||||
"wallet_address": address,
|
||||
|
||||
Reference in New Issue
Block a user