md rework. new code

This commit is contained in:
Dobromir Popov
2026-07-08 17:59:08 +02:00
parent 194fa1d926
commit e06969fcb5
5 changed files with 563 additions and 582 deletions

View File

@@ -1680,6 +1680,66 @@ def test_preset_startup_rejects_pinned_shard_above_memory_budget(tmp_path, monke
tracker.stop()
def test_network_auto_join_clips_oversized_cpu_assignment(tmp_path, monkeypatch, capsys):
"""Old trackers may assign too many CPU layers; node clips before model load."""
import meshnet_node.startup as startup_mod
torch_calls: list[dict] = []
registrations: list[dict] = []
class FakeBackend:
total_layers = 40
class FakeTorchNodeServer:
def __init__(self, **kwargs):
torch_calls.append(kwargs)
self.backend = FakeBackend()
self.tracker_node_id = None
def start(self):
return 7000
def stop(self):
pass
oversized_assignment = {
"hf_repo": "unsloth/Qwen3.6-35B-A3B",
"model": "qwen3.6-35b-a3b",
"shard_start": 0,
"shard_end": 36,
"num_layers": 40,
"gap_found": False,
"bytes_per_layer": {"bfloat16": 1_797_594_419},
"model_sources": [],
}
monkeypatch.setattr(
startup_mod,
"detect_hardware",
lambda: {"device": "cpu", "gpu_name": None, "vram_mb": 0, "ram_mb": 79 * 1024},
)
monkeypatch.setattr(startup_mod, "TorchNodeServer", FakeTorchNodeServer)
monkeypatch.setattr(startup_mod, "_get_json", lambda *_args, **_kwargs: oversized_assignment)
monkeypatch.setattr(startup_mod, "_post_json", lambda _url, payload: registrations.append(payload) or {"node_id": "n1"})
monkeypatch.setattr(startup_mod, "_start_heartbeat", lambda *_args, **_kwargs: None)
monkeypatch.setattr(startup_mod, "model_metadata_for", lambda *_args, **_kwargs: {"num_layers": 40})
node = run_startup(
tracker_url="http://127.0.0.1:8080",
wallet_path=tmp_path / "wallet.json",
tracker_source_disabled=True,
)
try:
assert torch_calls[0]["shard_start"] == 0
assert torch_calls[0]["shard_end"] == 24
assert registrations[0]["shard_end"] == 24
output = capsys.readouterr().out
assert "CPU-safe runtime budget fits 25/40 layers" in output
assert "layers 0-24" in output
finally:
node.stop()
def test_preset_model_with_hf_repo_loads_torch_backend(tmp_path, monkeypatch, capsys):
"""Named presets that advertise hf_repo must load TorchNodeServer, not the stub server."""
import meshnet_node.startup as startup_mod
@@ -1996,6 +2056,55 @@ def test_network_assign_gap_found_field():
tracker.stop()
def test_network_assign_uses_conservative_cpu_runtime_budget():
"""CPU assignments leave headroom for partial-load overhead, not just raw weights."""
import json as _json
import urllib.request as _ur
tracker = TrackerServer(model_presets={
"qwen3.6-35b-a3b": {
"hf_repo": "unsloth/Qwen3.6-35B-A3B",
"aliases": ["unsloth/Qwen3.6-35B-A3B"],
"layers_start": 0,
"layers_end": 39,
"recommended": True,
"bytes_per_layer": {"bfloat16": 1_797_594_419},
},
})
port = tracker.start()
try:
data = _json.dumps({
"endpoint": "http://127.0.0.1:9200",
"model": "qwen3.6-35b-a3b",
"hf_repo": "unsloth/Qwen3.6-35B-A3B",
"num_layers": 40,
"shard_start": 0,
"shard_end": 39,
"hardware_profile": {},
"score": 1.0,
}).encode()
req = _ur.Request(
f"http://127.0.0.1:{port}/v1/nodes/register",
data=data,
headers={"Content-Type": "application/json"},
method="POST",
)
with _ur.urlopen(req) as r:
r.read()
resp = _get_json(
f"http://127.0.0.1:{port}/v1/network/assign"
"?device=cpu&vram_mb=0&ram_mb=80896"
"&hf_repo=unsloth/Qwen3.6-35B-A3B"
)
assert resp["gap_found"] is False
assert resp["shard_start"] == 0
assert resp["shard_end"] == 24
finally:
tracker.stop()
def test_route_finds_hf_model_across_two_nodes():
"""Tracker /v1/route returns ordered route for HF model even without a preset."""
import json as _json