fix model registration and anouncement. added console panel

This commit is contained in:
Dobromir Popov
2026-07-07 14:24:37 +02:00
parent 0e8acf5d59
commit 339577a26c
9 changed files with 732 additions and 190 deletions

View File

@@ -399,7 +399,7 @@ def test_download_shard_uses_huggingface_when_repo_is_assigned(tmp_path, monkeyp
progress=False,
)
assert shard_dir == tmp_path / "tiny-llama" / "layers_0-3"
assert shard_dir == tmp_path / "tiny-llama"
assert calls == [{
"repo_id": "org/tiny-llama-shards",
"cache_dir": str(tmp_path),
@@ -407,6 +407,54 @@ def test_download_shard_uses_huggingface_when_repo_is_assigned(tmp_path, monkeyp
}]
def test_download_shard_reuses_model_cache_for_narrower_layer_range(
tmp_path,
monkeypatch,
):
"""A wider cached shard satisfies a later narrower assignment for the same model."""
cache_dir = tmp_path / "cache"
model_dir = cache_dir / "tiny-llama"
model_dir.mkdir(parents=True)
(model_dir / "config.json").write_bytes(b"{}")
(model_dir / "model-00001-of-00002.safetensors").write_bytes(b"a" * 3)
(model_dir / "model-00002-of-00002.safetensors").write_bytes(b"b" * 5)
def unexpected_urlopen(*args, **kwargs):
raise AssertionError("cached files should avoid tracker download")
def unexpected_snapshot_download(*args, **kwargs):
raise AssertionError("cached files should avoid HuggingFace download")
monkeypatch.setattr(urllib.request, "urlopen", unexpected_urlopen)
monkeypatch.setitem(
sys.modules,
"huggingface_hub",
types.SimpleNamespace(snapshot_download=unexpected_snapshot_download),
)
shard_dir = download_shard(
"tiny-llama",
0,
1,
cache_dir=cache_dir,
hf_repo="org/tiny-llama-shards",
model_sources=[{
"type": "tracker",
"url": "http://tracker/v1/model-files/download?model=tiny-llama",
"files": ["config.json", "model-00001-of-00002.safetensors"],
"file_sizes": {
"config.json": 2,
"model-00001-of-00002.safetensors": 3,
},
}],
peers=[{"endpoint": "http://peer", "checksum": "unused"}],
progress=False,
)
assert shard_dir == model_dir
assert (model_dir / "model-00002-of-00002.safetensors").read_bytes() == b"b" * 5
def test_download_shard_prefers_tracker_model_source_over_huggingface(
tmp_path,
monkeypatch,
@@ -1329,12 +1377,7 @@ def test_full_startup_sequence(tmp_path):
tracker.stop()
def test_second_node_downloads_same_shard_from_peer_without_huggingface(
tmp_path,
monkeypatch,
capsys,
):
"""Node A downloads from HF stub; node B downloads same assignment from node A."""
def test_preset_model_startup_starts_heartbeat(tmp_path, monkeypatch):
import meshnet_node.startup as startup_mod
monkeypatch.setattr(
@@ -1342,6 +1385,53 @@ def test_second_node_downloads_same_shard_from_peer_without_huggingface(
"detect_hardware",
lambda: {"device": "cpu", "gpu_name": None, "vram_mb": 0},
)
heartbeat_calls = []
monkeypatch.setattr(
startup_mod,
"_start_heartbeat",
lambda *args, **kwargs: heartbeat_calls.append((args, kwargs)),
)
tracker = TrackerServer(model_presets={"stub-model": {"layers_start": 0, "layers_end": 15}})
tracker_port = tracker.start()
tracker_url = f"http://127.0.0.1:{tracker_port}"
try:
node = run_startup(
tracker_url=tracker_url,
model="stub-model",
wallet_path=tmp_path / "wallet.json",
cache_dir=tmp_path / "shards",
)
try:
assert len(heartbeat_calls) == 1
args, kwargs = heartbeat_calls[0]
assert args[0] == tracker_url
assert args[2]["model"] == "stub-model"
assert kwargs["node_ref"] is node
finally:
node.stop()
finally:
tracker.stop()
def test_real_model_startup_registers_downloaded_inventory_without_checksum(
tmp_path,
monkeypatch,
capsys,
):
"""Real model folders are reported as inventory without hashing their contents."""
import meshnet_node.startup as startup_mod
monkeypatch.setattr(
startup_mod,
"detect_hardware",
lambda: {"device": "cpu", "gpu_name": None, "vram_mb": 0},
)
monkeypatch.setattr(
startup_mod,
"compute_shard_checksum",
lambda _path: (_ for _ in ()).throw(AssertionError("real model startup must not hash model files")),
)
hf_calls = []
def fake_snapshot_download(repo_id, cache_dir, local_dir):
@@ -1365,36 +1455,75 @@ def test_second_node_downloads_same_shard_from_peer_without_huggingface(
})
tracker_port = tracker.start()
tracker_url = f"http://127.0.0.1:{tracker_port}"
nodes = []
try:
node_a = run_startup(
node = run_startup(
tracker_url=tracker_url,
model="tiny-llama",
wallet_path=tmp_path / "wallet-a.json",
cache_dir=tmp_path / "node-a-shards",
wallet_path=tmp_path / "wallet.json",
cache_dir=tmp_path / "node-shards",
)
nodes.append(node_a)
assert len(hf_calls) == 1
node_b = run_startup(
tracker_url=tracker_url,
model="tiny-llama",
wallet_path=tmp_path / "wallet-b.json",
cache_dir=tmp_path / "node-b-shards",
)
nodes.append(node_b)
assert len(hf_calls) == 1
assert (tmp_path / "node-b-shards" / "tiny-llama" / "layers_0-15" / "weights.json").exists()
output = capsys.readouterr().out
assert "download source: HuggingFace" in output
assert "download source: peer" in output
finally:
for node in reversed(nodes):
try:
assert len(hf_calls) == 1
assert (tmp_path / "node-shards" / "tiny-llama" / "weights.json").exists()
output = capsys.readouterr().out
assert "Cached at:" in output
network_map = _get_json(f"{tracker_url}/v1/network/map")
registered = network_map["nodes"][0]
assert registered["downloaded_models"] == [{
"model": "tiny-llama",
"shard_start": 0,
"shard_end": 15,
"path": str(tmp_path / "node-shards" / "tiny-llama"),
"file_count": 1,
"total_bytes": (tmp_path / "node-shards" / "tiny-llama" / "weights.json").stat().st_size,
"hf_repo": "org/tiny-llama-shards",
}]
finally:
node.stop()
finally:
tracker.stop()
def test_downloaded_model_inventory_reports_local_model_percentage(tmp_path):
import meshnet_node.startup as startup_mod
model_dir = tmp_path / "models" / "tiny-llama"
model_dir.mkdir(parents=True)
(model_dir / "config.json").write_bytes(b"{}")
(model_dir / "weights-a.safetensors").write_bytes(b"a" * 3)
inventory = startup_mod._downloaded_model_inventory(
"tiny-llama",
0,
1,
model_dir,
hf_repo="org/tiny-llama",
model_sources=[{
"full_files": ["config.json", "weights-a.safetensors", "weights-b.safetensors"],
"file_sizes": {
"config.json": 2,
"weights-a.safetensors": 3,
"weights-b.safetensors": 5,
},
}],
)
assert inventory == [{
"model": "tiny-llama",
"shard_start": 0,
"shard_end": 1,
"path": str(model_dir),
"file_count": 2,
"total_bytes": 5,
"hf_repo": "org/tiny-llama",
"expected_file_count": 3,
"local_expected_file_count": 2,
"expected_bytes": 10,
"local_expected_bytes": 5,
"local_model_percentage": 50.0,
}]
def test_network_assign_gap_found_field():
"""network/assign sets gap_found=True when a real gap exists, False when fully covered."""
import json as _json
@@ -1587,6 +1716,30 @@ def test_startup_cpu_fallback(tmp_path, monkeypatch):
# --------------------------------------------------- layer detection (US: composite configs)
def test_detect_num_layers_prefers_flattened_local_model_config(tmp_path, monkeypatch):
import meshnet_node.startup as startup_mod
model_dir = tmp_path / "Qwen3.6-35B-A3B"
model_dir.mkdir()
(model_dir / "config.json").write_text("{}")
calls = []
class AutoConfigStub:
@staticmethod
def from_pretrained(model_id, cache_dir=None):
calls.append({"model_id": model_id, "cache_dir": cache_dir})
return types.SimpleNamespace(num_hidden_layers=37)
monkeypatch.setitem(
sys.modules,
"transformers",
types.SimpleNamespace(AutoConfig=AutoConfigStub),
)
assert startup_mod._detect_num_layers("unsloth/Qwen3.6-35B-A3B", cache_dir=tmp_path) == 37
assert calls == [{"model_id": str(model_dir), "cache_dir": None}]
def test_layers_from_config_top_level():
from meshnet_node.model_catalog import layers_from_config