ldhldh commited on
Commit
1576271
ยท
1 Parent(s): 95b37fc

Upload health.py

Browse files
Files changed (1) hide show
  1. health.py +124 -0
health.py ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import datetime
2
+ import time
3
+ from collections import Counter
4
+ from contextlib import suppress
5
+ from dataclasses import asdict
6
+ from functools import partial
7
+
8
+ import hivemind
9
+ import numpy as np
10
+ from multiaddr import Multiaddr
11
+ from petals.data_structures import UID_DELIMITER, ServerState
12
+ from petals.utils.dht import compute_spans, get_remote_module_infos
13
+
14
+ import config
15
+ from data_structures import ModelInfo
16
+ from p2p_utils import check_reachability_parallel, get_peers_ips, extract_peer_ip_info
17
+
18
+ logger = hivemind.get_logger(__name__)
19
+
20
+
21
+ def fetch_health_state(dht: hivemind.DHT) -> dict:
22
+ start_time = time.perf_counter()
23
+ bootstrap_peer_ids = []
24
+ for addr in config.INITIAL_PEERS:
25
+ peer_id = hivemind.PeerID.from_base58(Multiaddr(addr)["p2p"])
26
+ if peer_id not in bootstrap_peer_ids:
27
+ bootstrap_peer_ids.append(peer_id)
28
+
29
+ reach_infos = dht.run_coroutine(partial(check_reachability_parallel, bootstrap_peer_ids))
30
+ bootstrap_states = ["online" if reach_infos[peer_id]["ok"] else "unreachable" for peer_id in bootstrap_peer_ids]
31
+
32
+ models = config.MODELS[:]
33
+ model_index = dht.get("_petals.models", latest=True)
34
+ if model_index is not None and isinstance(model_index.value, dict):
35
+ official_dht_prefixes = {model.dht_prefix for model in models}
36
+ custom_models = []
37
+ for dht_prefix, model in model_index.value.items():
38
+ if dht_prefix in official_dht_prefixes:
39
+ continue
40
+ with suppress(TypeError, ValueError):
41
+ model_info = ModelInfo.from_dict(model.value)
42
+ if model_info.repository is None or not model_info.repository.startswith("https://huggingface.co/"):
43
+ continue
44
+ model_info.dht_prefix = dht_prefix
45
+ model_info.official = False
46
+ custom_models.append(model_info)
47
+ models.extend(sorted(custom_models, key=lambda info: (-info.num_blocks, info.dht_prefix)))
48
+ logger.info(f"Fetching info for models {[info.name for info in models]}")
49
+
50
+ block_uids = [f"{model.dht_prefix}{UID_DELIMITER}{i}" for model in models for i in range(model.num_blocks)]
51
+ module_infos = get_remote_module_infos(dht, block_uids, latest=True)
52
+
53
+ model_servers = {}
54
+ all_servers = {}
55
+ offset = 0
56
+ for model in models:
57
+ model_servers[model.dht_prefix] = compute_spans(
58
+ module_infos[offset : offset + model.num_blocks], min_state=ServerState.OFFLINE
59
+ )
60
+ all_servers.update(model_servers[model.dht_prefix])
61
+ offset += model.num_blocks
62
+
63
+ online_servers = [peer_id for peer_id, span in all_servers.items() if span.state == ServerState.ONLINE]
64
+
65
+ reach_infos.update(dht.run_coroutine(partial(check_reachability_parallel, online_servers, fetch_info=True)))
66
+ peers_info = {str(peer.peer_id): {"location": extract_peer_ip_info(str(peer.addrs[0])), "multiaddrs": [str(multiaddr) for multiaddr in peer.addrs]} for peer in dht.run_coroutine(get_peers_ips)}
67
+
68
+ top_contributors = Counter()
69
+ model_reports = []
70
+ for model in models:
71
+ block_healthy = np.zeros(model.num_blocks, dtype=bool)
72
+ server_rows = []
73
+ for peer_id, span in sorted(model_servers[model.dht_prefix].items()):
74
+ reachable = reach_infos[peer_id]["ok"] if peer_id in reach_infos else True
75
+ state = span.state.name.lower() if reachable else "unreachable"
76
+ if state == "online":
77
+ block_healthy[span.start : span.end] = True
78
+
79
+ show_public_name = state == "online" and span.length >= 10
80
+ if model.official and span.server_info.public_name and show_public_name:
81
+ top_contributors[span.server_info.public_name] += span.length
82
+
83
+ row = {
84
+ "short_peer_id": "..." + str(peer_id)[-6:],
85
+ "peer_id": peer_id,
86
+ "peer_ip_info": peers_info.get(str(peer_id), "unknown"),
87
+ "show_public_name": show_public_name,
88
+ "state": state,
89
+ "span": span,
90
+ "adapters": [dict(name=name, short_name=name.split("/")[-1]) for name in span.server_info.adapters],
91
+ "pings_to_me": {
92
+ str(origin_id): origin.server_info.next_pings[str(peer_id)]
93
+ for origin_id, origin in model_servers[model.dht_prefix].items()
94
+ if origin.server_info.next_pings is not None and str(peer_id) in origin.server_info.next_pings
95
+ },
96
+ }
97
+ if span.server_info.cache_tokens_left is not None:
98
+ # We use num_blocks * 2 to account for both keys and values
99
+ row["cache_tokens_left_per_block"] = span.server_info.cache_tokens_left // (span.length * 2)
100
+ server_rows.append(row)
101
+
102
+ model_reports.append(
103
+ dict(
104
+ name=model.name,
105
+ short_name=model.short_name,
106
+ state="healthy" if block_healthy.all() else "broken",
107
+ server_rows=server_rows,
108
+ **asdict(model),
109
+ )
110
+ )
111
+
112
+ reachability_issues = [
113
+ dict(peer_id=peer_id, err=info["error"]) for peer_id, info in sorted(reach_infos.items()) if not info["ok"]
114
+ ]
115
+
116
+ return dict(
117
+ bootstrap_states=bootstrap_states,
118
+ top_contributors=top_contributors,
119
+ model_reports=model_reports,
120
+ reachability_issues=reachability_issues,
121
+ last_updated=datetime.datetime.now(datetime.timezone.utc),
122
+ update_period=config.UPDATE_PERIOD,
123
+ update_duration=time.perf_counter() - start_time
124
+ )