AlexNijjar commited on
Commit
b343c97
·
1 Parent(s): 06f8be5

Update to new format

Browse files
src/__init__.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import datetime
2
+ from typing import TypeAlias
3
+ from zoneinfo import ZoneInfo
4
+
5
+ TIMEZONE = ZoneInfo("America/Los_Angeles")
6
+ START_DATE = datetime(2024, 11, 9)
7
+
8
+ Uid: TypeAlias = int
9
+ Hotkey: TypeAlias = str
src/app.py CHANGED
@@ -2,16 +2,16 @@ import gradio as gr
2
 
3
  from chain_data import sync_metagraph
4
  from leaderboard import create_leaderboard, create_dropdown
 
5
  from submissions import create_submissions
6
  from validator_states import create_validator_states
7
  from validator_weights import create_weights
8
- from model_demo import create_demo
9
  from wandb_data import sync
10
 
11
 
12
  def main():
13
- sync_metagraph(timeout=1000)
14
- sync(timeout=1000)
15
  with gr.Blocks(css=".typewriter {font-family: 'JMH Typewriter', sans-serif;}", fill_height=True, fill_width=True) as app:
16
  with gr.Tab("Leaderboard") as leaderboard_tab:
17
  dropdown = gr.Dropdown()
 
2
 
3
  from chain_data import sync_metagraph
4
  from leaderboard import create_leaderboard, create_dropdown
5
+ from model_demo import create_demo
6
  from submissions import create_submissions
7
  from validator_states import create_validator_states
8
  from validator_weights import create_weights
 
9
  from wandb_data import sync
10
 
11
 
12
  def main():
13
+ sync_metagraph()
14
+ sync()
15
  with gr.Blocks(css=".typewriter {font-family: 'JMH Typewriter', sans-serif;}", fill_height=True, fill_width=True) as app:
16
  with gr.Tab("Leaderboard") as leaderboard_tab:
17
  dropdown = gr.Dropdown()
src/chain_data.py CHANGED
@@ -1,4 +1,4 @@
1
- from concurrent.futures import ThreadPoolExecutor
2
  from dataclasses import dataclass
3
  from datetime import datetime, timedelta
4
  from enum import Enum
@@ -12,15 +12,19 @@ from fiber.chain.models import Node
12
  from substrateinterface.storage import StorageKey
13
 
14
  from network_commitments import Decoder
15
- from wandb_data import TIMEZONE, Hotkey, Uid
 
 
16
 
17
  Weight: TypeAlias = float
18
  Incentive: TypeAlias = float
19
 
 
20
  class ContestId(Enum):
21
  FLUX_NVIDIA_4090 = 0
22
  SDXL_NEWDREAM_NVIDIA_4090 = 1
23
 
 
24
  @dataclass
25
  class Commitment:
26
  provider: str
@@ -47,6 +51,7 @@ class Commitment:
47
  def get_repo_link(self):
48
  return f"https://{self.provider}/{self.repository}"
49
 
 
50
  SPEC_VERSION = 7
51
  NET_UID = 39
52
  WEIGHTS_BY_MINER: dict[Hotkey, list[tuple[Hotkey, Weight]]] = {}
@@ -128,11 +133,15 @@ def fetch_identities(block: int):
128
  for hotkey, node in metagraph.nodes.items():
129
  for storage, info in identities:
130
  if node.coldkey != storage.params[0]: continue
131
- if info != None: # noqa
132
  VALIDATOR_IDENTITIES[hotkey] = info.value["name"]
133
  break
134
 
 
135
  def fetch_commitments(block: int):
 
 
 
136
  COMMITMENTS.clear()
137
  storage_keys: list[StorageKey] = []
138
  for hotkey, node in metagraph.nodes.items():
@@ -172,7 +181,7 @@ last_identity_sync: datetime = datetime.fromtimestamp(0, TIMEZONE)
172
  last_commitment_sync: datetime = datetime.fromtimestamp(0, TIMEZONE)
173
 
174
 
175
- def sync_metagraph(timeout: int = 10):
176
  global substrate
177
  global last_sync
178
  now = datetime.now(TIMEZONE)
@@ -180,7 +189,7 @@ def sync_metagraph(timeout: int = 10):
180
  return
181
  last_sync = now
182
 
183
- def sync_task():
184
  print("Syncing metagraph...")
185
  block = substrate.get_block_number(None) # type: ignore
186
  metagraph.sync_nodes()
@@ -203,13 +212,6 @@ def sync_metagraph(timeout: int = 10):
203
  print("Syncing commitments...")
204
  last_commitment_sync = now
205
  fetch_commitments(block)
206
-
207
- with ThreadPoolExecutor(max_workers=1) as executor:
208
- future = executor.submit(sync_task)
209
- try:
210
- future.result(timeout=timeout)
211
- except TimeoutError:
212
- print("Timed out while syncing metagraph")
213
- except Exception as e:
214
- print(f"Error occurred while syncing metagraph: {e}")
215
- substrate = get_substrate()
 
1
+ import os
2
  from dataclasses import dataclass
3
  from datetime import datetime, timedelta
4
  from enum import Enum
 
12
  from substrateinterface.storage import StorageKey
13
 
14
  from network_commitments import Decoder
15
+ from src import Hotkey, Uid, TIMEZONE
16
+
17
+ DISABLE_COMMITMENTS_FETCH = int(os.getenv("DISABLE_COMMITMENTS_FETCH") or 0) > 0
18
 
19
  Weight: TypeAlias = float
20
  Incentive: TypeAlias = float
21
 
22
+
23
  class ContestId(Enum):
24
  FLUX_NVIDIA_4090 = 0
25
  SDXL_NEWDREAM_NVIDIA_4090 = 1
26
 
27
+
28
  @dataclass
29
  class Commitment:
30
  provider: str
 
51
  def get_repo_link(self):
52
  return f"https://{self.provider}/{self.repository}"
53
 
54
+
55
  SPEC_VERSION = 7
56
  NET_UID = 39
57
  WEIGHTS_BY_MINER: dict[Hotkey, list[tuple[Hotkey, Weight]]] = {}
 
133
  for hotkey, node in metagraph.nodes.items():
134
  for storage, info in identities:
135
  if node.coldkey != storage.params[0]: continue
136
+ if info != None: # noqa
137
  VALIDATOR_IDENTITIES[hotkey] = info.value["name"]
138
  break
139
 
140
+
141
  def fetch_commitments(block: int):
142
+ if DISABLE_COMMITMENTS_FETCH:
143
+ return
144
+
145
  COMMITMENTS.clear()
146
  storage_keys: list[StorageKey] = []
147
  for hotkey, node in metagraph.nodes.items():
 
181
  last_commitment_sync: datetime = datetime.fromtimestamp(0, TIMEZONE)
182
 
183
 
184
+ def sync_metagraph():
185
  global substrate
186
  global last_sync
187
  now = datetime.now(TIMEZONE)
 
189
  return
190
  last_sync = now
191
 
192
+ try:
193
  print("Syncing metagraph...")
194
  block = substrate.get_block_number(None) # type: ignore
195
  metagraph.sync_nodes()
 
212
  print("Syncing commitments...")
213
  last_commitment_sync = now
214
  fetch_commitments(block)
215
+ except Exception as e:
216
+ print(f"Error occurred while syncing metagraph: {e}")
217
+ substrate = get_substrate()
 
 
 
 
 
 
 
src/leaderboard.py CHANGED
@@ -7,6 +7,7 @@ from wandb_data import get_current_runs
7
 
8
  DEFAULT_VALIDATOR_UID = int(os.environ["DEFAULT_VALIDATOR_UID"])
9
 
 
10
  def create_dropdown() -> gr.Dropdown:
11
  choices: list[tuple[str, int]] = []
12
  runs = get_current_runs()
@@ -26,17 +27,18 @@ def create_dropdown() -> gr.Dropdown:
26
  label="Source Validator"
27
  )
28
 
 
29
  def create_leaderboard(validator_uid) -> gr.Dataframe:
30
  data: list[list] = []
31
  runs = get_current_runs()
32
  for run in runs:
33
  if run.uid != validator_uid:
34
  continue
35
- for submission in run.submissions.values():
36
  data.append([
37
  submission.info.uid,
38
  f"[{'/'.join(submission.info.repository.split('/')[-2:])}]({submission.info.repository})",
39
- submission.tier,
40
  round(submission.score, 3),
41
  f"{submission.metrics.generation_time:.3f}s",
42
  f"{submission.average_similarity * 100:.3f}%",
@@ -46,13 +48,13 @@ def create_leaderboard(validator_uid) -> gr.Dataframe:
46
  f"{submission.metrics.load_time:.3f}s",
47
  f"[{submission.info.block}](https://taostats.io/block/{submission.info.block})",
48
  f"[{submission.info.revision}]({submission.info.repository}/commit/{submission.info.revision})",
49
- f"[{submission.info.hotkey[:6]}...](https://taostats.io/hotkey/{submission.info.hotkey})",
50
  ])
51
 
52
- data.sort(key=lambda x: (-x[2], int(x[10].split('[')[1].split(']')[0])))
53
 
54
  return gr.Dataframe(
55
- pd.DataFrame(data, columns=["UID", "Model", "Tier", "Score", "Gen Time", "Similarity", "Size", "VRAM Usage", "Power Usage", "Load Time", "Block", "Revision", "Hotkey"]),
56
  datatype=["number", "markdown", "number", "number", "markdown", "markdown", "markdown", "markdown", "markdown", "markdown", "markdown", "markdown", "markdown"],
57
  interactive=False,
58
  max_height=800,
 
7
 
8
  DEFAULT_VALIDATOR_UID = int(os.environ["DEFAULT_VALIDATOR_UID"])
9
 
10
+
11
  def create_dropdown() -> gr.Dropdown:
12
  choices: list[tuple[str, int]] = []
13
  runs = get_current_runs()
 
27
  label="Source Validator"
28
  )
29
 
30
+
31
  def create_leaderboard(validator_uid) -> gr.Dataframe:
32
  data: list[list] = []
33
  runs = get_current_runs()
34
  for run in runs:
35
  if run.uid != validator_uid:
36
  continue
37
+ for hotkey, submission in run.submissions.items():
38
  data.append([
39
  submission.info.uid,
40
  f"[{'/'.join(submission.info.repository.split('/')[-2:])}]({submission.info.repository})",
41
+ submission.rank + 1,
42
  round(submission.score, 3),
43
  f"{submission.metrics.generation_time:.3f}s",
44
  f"{submission.average_similarity * 100:.3f}%",
 
48
  f"{submission.metrics.load_time:.3f}s",
49
  f"[{submission.info.block}](https://taostats.io/block/{submission.info.block})",
50
  f"[{submission.info.revision}]({submission.info.repository}/commit/{submission.info.revision})",
51
+ f"[{hotkey[:6]}...](https://taostats.io/hotkey/{hotkey})",
52
  ])
53
 
54
+ data.sort(key=lambda x: (x[2], int(x[10].split('[')[1].split(']')[0])))
55
 
56
  return gr.Dataframe(
57
+ pd.DataFrame(data, columns=["UID", "Model", "Rank", "Score", "Gen Time", "Similarity", "Size", "VRAM Usage", "Power Usage", "Load Time", "Block", "Revision", "Hotkey"]),
58
  datatype=["number", "markdown", "number", "number", "markdown", "markdown", "markdown", "markdown", "markdown", "markdown", "markdown", "markdown", "markdown"],
59
  interactive=False,
60
  max_height=800,
src/model_demo.py CHANGED
@@ -17,6 +17,7 @@ SERVER_API_KEY = os.environ["SERVER_API_KEY"]
17
  current_model: str | None = None
18
  last_current_model_sync: datetime = datetime.fromtimestamp(0, TIMEZONE)
19
 
 
20
  def get_current_model() -> str | None:
21
  global current_model
22
  global last_current_model_sync
@@ -36,7 +37,6 @@ def get_current_model() -> str | None:
36
  return None
37
 
38
 
39
-
40
  def image_from_base64(image_data: str) -> Image:
41
  image_buffer = BytesIO(base64.b64decode(image_data))
42
  image = Image.open(image_buffer)
 
17
  current_model: str | None = None
18
  last_current_model_sync: datetime = datetime.fromtimestamp(0, TIMEZONE)
19
 
20
+
21
  def get_current_model() -> str | None:
22
  global current_model
23
  global last_current_model_sync
 
37
  return None
38
 
39
 
 
40
  def image_from_base64(image_data: str) -> Image:
41
  image_buffer = BytesIO(base64.b64decode(image_data))
42
  image = Image.open(image_buffer)
src/network_commitments.py CHANGED
@@ -1,6 +1,5 @@
1
  from struct import pack, unpack
2
 
3
-
4
  _UINT_16_SIZE = 2
5
  _UINT_32_SIZE = 4
6
 
 
1
  from struct import pack, unpack
2
 
 
3
  _UINT_16_SIZE = 2
4
  _UINT_32_SIZE = 4
5
 
src/submissions.py CHANGED
@@ -2,18 +2,22 @@ import gradio as gr
2
  import pandas as pd
3
 
4
  from chain_data import sync_metagraph, COMMITMENTS, UIDS_BY_HOTKEY
5
- from wandb_data import get_current_runs, Run, Uid
 
6
 
7
- def get_status(run: Run, uid: Uid, block: int) -> tuple[str, str]:
8
- if all(not submission.get(uid) or block > submission[uid].info.block for submission in [run.submissions, run.invalid_submissions]):
 
9
  return "Pending", "orange"
10
 
11
- if uid in run.submissions:
12
  return "Done", "springgreen"
13
- elif uid in run.invalid_submissions:
 
14
  return "Invalid", "red"
15
- else:
16
- return "Pending", "orange"
 
17
 
18
  def create_submissions() -> gr.Dataframe:
19
  data: list[list] = []
@@ -21,9 +25,8 @@ def create_submissions() -> gr.Dataframe:
21
  runs = sorted(get_current_runs(), key=lambda run: run.uid)
22
 
23
  for hotkey, commitment in COMMITMENTS.items():
24
- uid = UIDS_BY_HOTKEY[hotkey]
25
  row = [
26
- uid,
27
  f"[{'/'.join(commitment.get_repo_link().split('/')[-2:])}]({commitment.get_repo_link()})",
28
  f"[{commitment.block}](https://taostats.io/block/{commitment.block})",
29
  f"[{commitment.revision}]({commitment.get_repo_link()}/commit/{commitment.revision})",
@@ -32,7 +35,7 @@ def create_submissions() -> gr.Dataframe:
32
  ]
33
 
34
  for run in runs:
35
- status, color = get_status(run, uid, commitment.block)
36
  row.append(f"<span style='color: {color}'>{status}</span>")
37
 
38
  data.append(row)
 
2
  import pandas as pd
3
 
4
  from chain_data import sync_metagraph, COMMITMENTS, UIDS_BY_HOTKEY
5
+ from src import Hotkey
6
+ from wandb_data import get_current_runs, Run
7
 
8
+
9
+ def get_status(run: Run, hotkey: Hotkey, block: int) -> tuple[str, str]:
10
+ if hotkey in run.submissions and block > run.submissions[hotkey].info.block and hotkey not in run.invalid_submissions:
11
  return "Pending", "orange"
12
 
13
+ if hotkey in run.submissions:
14
  return "Done", "springgreen"
15
+
16
+ if hotkey in run.invalid_submissions:
17
  return "Invalid", "red"
18
+
19
+ return "Pending", "orange"
20
+
21
 
22
  def create_submissions() -> gr.Dataframe:
23
  data: list[list] = []
 
25
  runs = sorted(get_current_runs(), key=lambda run: run.uid)
26
 
27
  for hotkey, commitment in COMMITMENTS.items():
 
28
  row = [
29
+ UIDS_BY_HOTKEY[hotkey],
30
  f"[{'/'.join(commitment.get_repo_link().split('/')[-2:])}]({commitment.get_repo_link()})",
31
  f"[{commitment.block}](https://taostats.io/block/{commitment.block})",
32
  f"[{commitment.revision}]({commitment.get_repo_link()}/commit/{commitment.revision})",
 
35
  ]
36
 
37
  for run in runs:
38
+ status, color = get_status(run, hotkey, commitment.block)
39
  row.append(f"<span style='color: {color}'>{status}</span>")
40
 
41
  data.append(row)
src/validator_states.py CHANGED
@@ -5,10 +5,10 @@ import gradio as gr
5
  import pandas as pd
6
  from packaging import version
7
 
8
- from wandb_data import get_current_runs, Run
9
  from chain_data import get_nodes, UPDATED
 
10
 
11
- AVERAGE_BENCHMARK_TIME_WARNING_THRESHOLD = 180 # 3 minutes
12
  ETA_WARNING_THRESHOLD = 43200 # 12 hours
13
  UPDATED_WARNING_THRESHOLD = 1000
14
  VTRUST_WARNING_THRESHOLD = 0.75
@@ -30,7 +30,7 @@ def colorize(val, color: str) -> str:
30
  def create_validator_states() -> gr.Dataframe:
31
  data: list[list] = []
32
  runs = sorted(get_current_runs(), key=lambda run: run.uid)
33
- winners = [run.winner_uid for run in runs if run.winner_uid]
34
  winner_uid_mode = statistics.mode(winners) if winners else None
35
  latest_version = get_latest_version(runs)
36
  for run in runs:
@@ -41,10 +41,10 @@ def create_validator_states() -> gr.Dataframe:
41
  run.name,
42
  colorize(run.version, "springgreen" if run.version == latest_version else "red"),
43
  colorize(run.status.name(), run.status.color()),
44
- colorize(run.winner_uid, "springgreen" if winner_uid_mode and run.winner_uid == winner_uid_mode else "orange" if run.winner_uid else "gray"),
45
  f"{min(run.total_submissions, len(run.submissions) + len(run.invalid_submissions))}/{run.total_submissions}",
46
  len(run.invalid_submissions),
47
- colorize(f"{timedelta(seconds=int(run.average_benchmark_time))}", "orange" if run.average_benchmark_time > AVERAGE_BENCHMARK_TIME_WARNING_THRESHOLD else "springgreen" if run.average_benchmark_time > 0 else "gray"),
48
  colorize(f"{timedelta(seconds=run.eta)}", "orange" if run.eta > ETA_WARNING_THRESHOLD else "springgreen" if run.eta > 0 else "gray"),
49
  colorize(f"{vtrust:.4f}", "springgreen" if vtrust > VTRUST_WARNING_THRESHOLD else "red"),
50
  colorize(updated, "springgreen" if updated < UPDATED_WARNING_THRESHOLD else "red"),
 
5
  import pandas as pd
6
  from packaging import version
7
 
 
8
  from chain_data import get_nodes, UPDATED
9
+ from wandb_data import get_current_runs, Run, BenchmarkStatus
10
 
11
+ AVERAGE_BENCHMARKING_TIME_WARNING_THRESHOLD = 180 # 3 minutes
12
  ETA_WARNING_THRESHOLD = 43200 # 12 hours
13
  UPDATED_WARNING_THRESHOLD = 1000
14
  VTRUST_WARNING_THRESHOLD = 0.75
 
30
  def create_validator_states() -> gr.Dataframe:
31
  data: list[list] = []
32
  runs = sorted(get_current_runs(), key=lambda run: run.uid)
33
+ winners = [run.winner_uid for run in runs if run.winner_uid and run.status == BenchmarkStatus.FINISHED]
34
  winner_uid_mode = statistics.mode(winners) if winners else None
35
  latest_version = get_latest_version(runs)
36
  for run in runs:
 
41
  run.name,
42
  colorize(run.version, "springgreen" if run.version == latest_version else "red"),
43
  colorize(run.status.name(), run.status.color()),
44
+ colorize(run.winner_uid, "springgreen" if winner_uid_mode and run.winner_uid == winner_uid_mode else "orange" if run.winner_uid and run.status == BenchmarkStatus.FINISHED else "gray"),
45
  f"{min(run.total_submissions, len(run.submissions) + len(run.invalid_submissions))}/{run.total_submissions}",
46
  len(run.invalid_submissions),
47
+ colorize(f"{timedelta(seconds=int(run.average_benchmarking_time))}", "orange" if run.average_benchmarking_time > AVERAGE_BENCHMARKING_TIME_WARNING_THRESHOLD else "springgreen" if run.average_benchmarking_time > 0 else "gray"),
48
  colorize(f"{timedelta(seconds=run.eta)}", "orange" if run.eta > ETA_WARNING_THRESHOLD else "springgreen" if run.eta > 0 else "gray"),
49
  colorize(f"{vtrust:.4f}", "springgreen" if vtrust > VTRUST_WARNING_THRESHOLD else "red"),
50
  colorize(updated, "springgreen" if updated < UPDATED_WARNING_THRESHOLD else "red"),
src/validator_weights.py CHANGED
@@ -22,6 +22,7 @@ def get_color_by_weight(weight: float) -> str:
22
  g = int(255 - ((1 - progress) * 50))
23
  return f"rgb(0, {g}, 0)"
24
 
 
25
  def get_active_weights() -> dict[Hotkey, list[tuple[Hotkey, Weight]]]:
26
  runs = get_current_runs()
27
  weights: dict[Hotkey, list[tuple[Hotkey, Weight]]] = {}
@@ -35,6 +36,7 @@ def get_active_weights() -> dict[Hotkey, list[tuple[Hotkey, Weight]]]:
35
 
36
  return weights
37
 
 
38
  def create_weights(include_inactive: bool) -> gr.Dataframe:
39
  data: list[list] = []
40
  sync_metagraph()
 
22
  g = int(255 - ((1 - progress) * 50))
23
  return f"rgb(0, {g}, 0)"
24
 
25
+
26
  def get_active_weights() -> dict[Hotkey, list[tuple[Hotkey, Weight]]]:
27
  runs = get_current_runs()
28
  weights: dict[Hotkey, list[tuple[Hotkey, Weight]]] = {}
 
36
 
37
  return weights
38
 
39
+
40
  def create_weights(include_inactive: bool) -> gr.Dataframe:
41
  data: list[list] = []
42
  sync_metagraph()
src/wandb_data.py CHANGED
@@ -1,22 +1,18 @@
1
  import os
2
- from concurrent.futures import ThreadPoolExecutor
3
  from dataclasses import dataclass
4
  from datetime import datetime, timedelta, timezone
5
  from enum import Enum
6
- from typing import TypeAlias
7
- from zoneinfo import ZoneInfo
8
 
9
  import wandb
10
  import wandb.apis.public as wapi
11
  from substrateinterface import Keypair
12
 
13
- WANDB_RUN_PATH = os.environ["WANDB_RUN_PATH"]
 
14
 
15
- TIMEZONE = ZoneInfo("America/Los_Angeles")
16
- START_DATE = datetime(2024, 11, 9)
17
 
18
- Uid: TypeAlias = int
19
- Hotkey: TypeAlias = str
20
 
21
 
22
  class BenchmarkStatus(Enum):
@@ -51,7 +47,6 @@ class MetricData:
51
  @dataclass
52
  class SubmissionInfo:
53
  uid: int
54
- hotkey: Hotkey
55
  repository: str
56
  revision: str
57
  block: int
@@ -63,16 +58,10 @@ class Submission:
63
  metrics: MetricData
64
  average_similarity: float
65
  min_similarity: float
66
- tier: int
67
  score: float
68
 
69
 
70
- @dataclass
71
- class InvalidSubmission:
72
- info: SubmissionInfo
73
- reason: str
74
-
75
-
76
  @dataclass
77
  class Run:
78
  start_date: datetime
@@ -81,29 +70,28 @@ class Run:
81
  name: str
82
  hotkey: str
83
  status: BenchmarkStatus
84
- average_benchmark_time: float
85
  eta: int
86
  winner_uid: int | None
87
  baseline_metrics: MetricData | None
88
  total_submissions: int
89
- submissions: dict[Uid, Submission]
90
- invalid_submissions: dict[Uid, InvalidSubmission]
91
 
92
 
93
  RUNS: dict[str, list[Run]] = {}
94
 
95
 
96
- def _is_valid_run(run: wapi.Run):
97
- required_config_keys = ["hotkey", "uid", "contest", "signature"]
98
 
99
  for key in required_config_keys:
100
  if key not in run.config:
101
  return False
102
 
103
  validator_hotkey = run.config["hotkey"]
104
- contest_name = run.config["contest"]
105
 
106
- signing_message = f"{run.name}:{validator_hotkey}:{contest_name}"
107
 
108
  return Keypair(validator_hotkey).verify(signing_message, run.config["signature"])
109
 
@@ -122,7 +110,8 @@ def _status_from_run(run: wapi.Run) -> BenchmarkStatus:
122
  return BenchmarkStatus.FAILED
123
  case "running":
124
  if "benchmarking_state" in run.summary:
125
- return BenchmarkStatus[run.summary["benchmarking_state"]]
 
126
  else:
127
  return BenchmarkStatus.INITIALIZING
128
  case _:
@@ -131,14 +120,15 @@ def _status_from_run(run: wapi.Run) -> BenchmarkStatus:
131
 
132
  def _add_runs(wandb_runs: list[wapi.Run]):
133
  for wandb_run in wandb_runs:
134
- if not _is_valid_run(wandb_run):
 
135
  continue
136
 
137
  metrics = wandb_run.summary
138
 
139
- submission_info: dict[Uid, SubmissionInfo] = {}
140
- submissions: dict[Uid, Submission] = {}
141
- invalid_submissions: dict[Uid, InvalidSubmission] = {}
142
 
143
  baseline_metrics: MetricData | None = None
144
  if "baseline" in metrics:
@@ -152,67 +142,65 @@ def _add_runs(wandb_runs: list[wapi.Run]):
152
  )
153
 
154
  if "submissions" in metrics:
155
- for uid, submission in metrics["submissions"].items():
156
- submission_info[uid] = SubmissionInfo(
157
- uid=int(uid),
158
- hotkey=submission["hotkey"],
159
- repository=submission["repository"],
160
- revision=submission["revision"],
 
 
161
  block=submission["block"],
162
  )
163
 
164
- if "benchmarks" in metrics:
165
- for uid, benchmark in metrics["benchmarks"].items():
166
- model = benchmark["model"]
167
- if uid not in submission_info:
168
  continue
169
- submissions[int(uid)] = Submission(
170
- info=submission_info[uid],
171
  metrics=MetricData(
172
- generation_time=float(model["generation_time"]),
173
- vram_used=float(model["vram_used"]),
174
- watts_used=float(model["watts_used"]),
175
- load_time=float(model["load_time"]),
176
- size=int(model["size"]),
177
  ),
178
  average_similarity=float(benchmark["average_similarity"]),
179
  min_similarity=float(benchmark["min_similarity"]),
180
- tier=int(benchmark["tier"]),
181
- score=float(benchmark["score"]),
182
  )
183
 
184
- if "invalid" in metrics:
185
- for uid, reason in metrics["invalid"].items():
186
- if not uid in submission_info:
187
- continue
188
- invalid_submissions[int(uid)] = InvalidSubmission(
189
- info=submission_info[uid],
190
- reason=reason,
191
- )
192
 
193
  status = _status_from_run(wandb_run)
194
  winners = sorted(
195
  submissions.values(),
196
- key=lambda submission: (submission.tier, -submission.info.block),
197
- reverse=True,
198
  )
199
- winner_uid = winners[0].info.uid if winners and status == status.FINISHED else None
200
 
201
- from chain_data import VALIDATOR_IDENTITIES
202
  uid = int(wandb_run.config["uid"])
203
  hotkey = wandb_run.config["hotkey"]
204
  date = _date_from_run(wandb_run)
205
  id = wandb_run.id
206
- average_benchmark_time = float(wandb_run.summary["average_benchmark_time"]) if "average_benchmark_time" in wandb_run.summary else 0
207
  run = Run(
208
  start_date=date,
209
- version=wandb_run.tags[1][8:],
210
  uid=uid,
211
  name=VALIDATOR_IDENTITIES.get(hotkey, f"{hotkey[:6]}..."),
212
  hotkey=hotkey,
213
  status=status,
214
- average_benchmark_time=average_benchmark_time,
215
- eta=max(int(average_benchmark_time * (len(submission_info) - len(submissions) - len(invalid_submissions))) if average_benchmark_time else 0, 0) if status != BenchmarkStatus.FINISHED else 0,
216
  winner_uid=winner_uid,
217
  baseline_metrics=baseline_metrics,
218
  total_submissions=len(submission_info),
@@ -264,35 +252,24 @@ def _fetch_current_runs(wandb_api: wandb.Api):
264
  last_sync: datetime = datetime.fromtimestamp(0, TIMEZONE)
265
 
266
 
267
- def sync(timeout: int = 10):
268
  global last_sync
269
  now = datetime.now(TIMEZONE)
270
  if now - last_sync < timedelta(seconds=60):
271
  return
272
  last_sync = now
273
 
274
- def sync_task():
275
- print("Syncing runs...")
276
- wandb_api = wandb.Api()
277
- if not RUNS:
278
- _fetch_history(wandb_api)
279
- else:
280
- _fetch_current_runs(wandb_api)
281
-
282
- with ThreadPoolExecutor(max_workers=1) as executor:
283
- future = executor.submit(sync_task)
284
- try:
285
- future.result(timeout=timeout)
286
- except TimeoutError:
287
- print("Timed out while syncing runs")
288
- except Exception as e:
289
- print(f"Error occurred while syncing runs: {e}")
290
 
291
 
292
  def get_current_runs() -> list[Run]:
293
- sync()
294
- from chain_data import sync_metagraph
295
  sync_metagraph()
 
296
 
297
  today = _get_contest_start()
298
 
 
1
  import os
 
2
  from dataclasses import dataclass
3
  from datetime import datetime, timedelta, timezone
4
  from enum import Enum
 
 
5
 
6
  import wandb
7
  import wandb.apis.public as wapi
8
  from substrateinterface import Keypair
9
 
10
+ from src import TIMEZONE, Hotkey
11
+ from chain_data import UIDS_BY_HOTKEY, VALIDATOR_IDENTITIES, sync_metagraph
12
 
13
+ WANDB_RUN_PATH = os.environ["WANDB_RUN_PATH"]
 
14
 
15
+ START_DATE = datetime(2024, 11, 29)
 
16
 
17
 
18
  class BenchmarkStatus(Enum):
 
47
  @dataclass
48
  class SubmissionInfo:
49
  uid: int
 
50
  repository: str
51
  revision: str
52
  block: int
 
58
  metrics: MetricData
59
  average_similarity: float
60
  min_similarity: float
61
+ rank: int
62
  score: float
63
 
64
 
 
 
 
 
 
 
65
  @dataclass
66
  class Run:
67
  start_date: datetime
 
70
  name: str
71
  hotkey: str
72
  status: BenchmarkStatus
73
+ average_benchmarking_time: float
74
  eta: int
75
  winner_uid: int | None
76
  baseline_metrics: MetricData | None
77
  total_submissions: int
78
+ submissions: dict[Hotkey, Submission]
79
+ invalid_submissions: set[Hotkey]
80
 
81
 
82
  RUNS: dict[str, list[Run]] = {}
83
 
84
 
85
+ def _is_valid_run(run: wapi.Run, version: str) -> bool:
86
+ required_config_keys = ["hotkey", "uid", "signature"]
87
 
88
  for key in required_config_keys:
89
  if key not in run.config:
90
  return False
91
 
92
  validator_hotkey = run.config["hotkey"]
 
93
 
94
+ signing_message = f"{version}:{validator_hotkey}"
95
 
96
  return Keypair(validator_hotkey).verify(signing_message, run.config["signature"])
97
 
 
110
  return BenchmarkStatus.FAILED
111
  case "running":
112
  if "benchmarking_state" in run.summary:
113
+ states = list(BenchmarkStatus)
114
+ return states[int(run.summary["benchmarking_state"])]
115
  else:
116
  return BenchmarkStatus.INITIALIZING
117
  case _:
 
120
 
121
  def _add_runs(wandb_runs: list[wapi.Run]):
122
  for wandb_run in wandb_runs:
123
+ version = wandb_run.tags[1][8:]
124
+ if not _is_valid_run(wandb_run, version):
125
  continue
126
 
127
  metrics = wandb_run.summary
128
 
129
+ submission_info: dict[Hotkey, SubmissionInfo] = {}
130
+ submissions: dict[Hotkey, Submission] = {}
131
+ invalid_submissions: set[Hotkey] = set()
132
 
133
  baseline_metrics: MetricData | None = None
134
  if "baseline" in metrics:
 
142
  )
143
 
144
  if "submissions" in metrics:
145
+ for hotkey, submission in metrics["submissions"].items():
146
+ uid = UIDS_BY_HOTKEY.get(hotkey)
147
+ if not uid:
148
+ continue
149
+ submission_info[hotkey] = SubmissionInfo(
150
+ uid=uid,
151
+ repository=submission["repository_info"]["url"],
152
+ revision=submission["repository_info"]["revision"],
153
  block=submission["block"],
154
  )
155
 
156
+ if "benchmarks" in metrics and "ranks" in metrics:
157
+ for hotkey, benchmark in metrics["benchmarks"].items():
158
+ benchmark_metrics = benchmark["metrics"]
159
+ if hotkey not in submission_info:
160
  continue
161
+ submissions[hotkey] = Submission(
162
+ info=submission_info[hotkey],
163
  metrics=MetricData(
164
+ generation_time=float(benchmark_metrics["generation_time"]),
165
+ vram_used=float(benchmark_metrics["vram_used"]),
166
+ watts_used=float(benchmark_metrics["watts_used"]),
167
+ load_time=float(benchmark_metrics["load_time"]),
168
+ size=int(benchmark_metrics["size"]),
169
  ),
170
  average_similarity=float(benchmark["average_similarity"]),
171
  min_similarity=float(benchmark["min_similarity"]),
172
+ rank=int(metrics["ranks"][hotkey]),
173
+ score=float(metrics["scores"][hotkey]),
174
  )
175
 
176
+ if "invalid_submissions" in metrics:
177
+ try:
178
+ for hotkey in metrics["invalid_submissions"]:
179
+ invalid_submissions.add(hotkey)
180
+ except KeyError:
181
+ ...
 
 
182
 
183
  status = _status_from_run(wandb_run)
184
  winners = sorted(
185
  submissions.values(),
186
+ key=lambda submission: (submission.rank, submission.info.block),
 
187
  )
188
+ winner_uid = winners[0].info.uid if winners else None
189
 
 
190
  uid = int(wandb_run.config["uid"])
191
  hotkey = wandb_run.config["hotkey"]
192
  date = _date_from_run(wandb_run)
193
  id = wandb_run.id
194
+ average_benchmarking_time = float(wandb_run.summary["average_benchmarking_time"]) if "average_benchmarking_time" in wandb_run.summary else 0
195
  run = Run(
196
  start_date=date,
197
+ version=version,
198
  uid=uid,
199
  name=VALIDATOR_IDENTITIES.get(hotkey, f"{hotkey[:6]}..."),
200
  hotkey=hotkey,
201
  status=status,
202
+ average_benchmarking_time=average_benchmarking_time,
203
+ eta=max(int(average_benchmarking_time * (len(submission_info) - len(submissions) - len(invalid_submissions))) if average_benchmarking_time else 0, 0) if status != BenchmarkStatus.FINISHED else 0,
204
  winner_uid=winner_uid,
205
  baseline_metrics=baseline_metrics,
206
  total_submissions=len(submission_info),
 
252
  last_sync: datetime = datetime.fromtimestamp(0, TIMEZONE)
253
 
254
 
255
+ def sync():
256
  global last_sync
257
  now = datetime.now(TIMEZONE)
258
  if now - last_sync < timedelta(seconds=60):
259
  return
260
  last_sync = now
261
 
262
+ print("Syncing runs...")
263
+ wandb_api = wandb.Api()
264
+ if not RUNS:
265
+ _fetch_history(wandb_api)
266
+ else:
267
+ _fetch_current_runs(wandb_api)
 
 
 
 
 
 
 
 
 
 
268
 
269
 
270
  def get_current_runs() -> list[Run]:
 
 
271
  sync_metagraph()
272
+ sync()
273
 
274
  today = _get_contest_start()
275