Spaces:
Sleeping
Sleeping
Commit ·
b343c97
1
Parent(s): 06f8be5
Update to new format
Browse files- src/__init__.py +9 -0
- src/app.py +3 -3
- src/chain_data.py +17 -15
- src/leaderboard.py +7 -5
- src/model_demo.py +1 -1
- src/network_commitments.py +0 -1
- src/submissions.py +13 -10
- src/validator_states.py +5 -5
- src/validator_weights.py +2 -0
- src/wandb_data.py +59 -82
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(
|
| 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()
|
|
|
|
| 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 |
-
|
| 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
|
|
|
|
|
|
|
| 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:
|
| 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(
|
| 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 |
-
|
| 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 |
-
|
| 208 |
-
|
| 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.
|
| 36 |
data.append([
|
| 37 |
submission.info.uid,
|
| 38 |
f"[{'/'.join(submission.info.repository.split('/')[-2:])}]({submission.info.repository})",
|
| 39 |
-
submission.
|
| 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"[{
|
| 50 |
])
|
| 51 |
|
| 52 |
-
data.sort(key=lambda x: (
|
| 53 |
|
| 54 |
return gr.Dataframe(
|
| 55 |
-
pd.DataFrame(data, columns=["UID", "Model", "
|
| 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
|
|
|
|
| 6 |
|
| 7 |
-
|
| 8 |
-
|
|
|
|
| 9 |
return "Pending", "orange"
|
| 10 |
|
| 11 |
-
if
|
| 12 |
return "Done", "springgreen"
|
| 13 |
-
|
|
|
|
| 14 |
return "Invalid", "red"
|
| 15 |
-
|
| 16 |
-
|
|
|
|
| 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 |
-
|
| 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,
|
| 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 |
-
|
| 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.
|
| 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 |
-
|
|
|
|
| 14 |
|
| 15 |
-
|
| 16 |
-
START_DATE = datetime(2024, 11, 9)
|
| 17 |
|
| 18 |
-
|
| 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 |
-
|
| 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 |
-
|
| 85 |
eta: int
|
| 86 |
winner_uid: int | None
|
| 87 |
baseline_metrics: MetricData | None
|
| 88 |
total_submissions: int
|
| 89 |
-
submissions: dict[
|
| 90 |
-
invalid_submissions:
|
| 91 |
|
| 92 |
|
| 93 |
RUNS: dict[str, list[Run]] = {}
|
| 94 |
|
| 95 |
|
| 96 |
-
def _is_valid_run(run: wapi.Run):
|
| 97 |
-
required_config_keys = ["hotkey", "uid", "
|
| 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"{
|
| 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 |
-
|
|
|
|
| 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 |
-
|
|
|
|
| 135 |
continue
|
| 136 |
|
| 137 |
metrics = wandb_run.summary
|
| 138 |
|
| 139 |
-
submission_info: dict[
|
| 140 |
-
submissions: dict[
|
| 141 |
-
invalid_submissions:
|
| 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
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
|
|
|
|
|
|
|
| 161 |
block=submission["block"],
|
| 162 |
)
|
| 163 |
|
| 164 |
-
if "benchmarks" in metrics:
|
| 165 |
-
for
|
| 166 |
-
|
| 167 |
-
if
|
| 168 |
continue
|
| 169 |
-
submissions[
|
| 170 |
-
info=submission_info[
|
| 171 |
metrics=MetricData(
|
| 172 |
-
generation_time=float(
|
| 173 |
-
vram_used=float(
|
| 174 |
-
watts_used=float(
|
| 175 |
-
load_time=float(
|
| 176 |
-
size=int(
|
| 177 |
),
|
| 178 |
average_similarity=float(benchmark["average_similarity"]),
|
| 179 |
min_similarity=float(benchmark["min_similarity"]),
|
| 180 |
-
|
| 181 |
-
score=float(
|
| 182 |
)
|
| 183 |
|
| 184 |
-
if "
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
reason=reason,
|
| 191 |
-
)
|
| 192 |
|
| 193 |
status = _status_from_run(wandb_run)
|
| 194 |
winners = sorted(
|
| 195 |
submissions.values(),
|
| 196 |
-
key=lambda submission: (submission.
|
| 197 |
-
reverse=True,
|
| 198 |
)
|
| 199 |
-
winner_uid = winners[0].info.uid if winners
|
| 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 |
-
|
| 207 |
run = Run(
|
| 208 |
start_date=date,
|
| 209 |
-
version=
|
| 210 |
uid=uid,
|
| 211 |
name=VALIDATOR_IDENTITIES.get(hotkey, f"{hotkey[:6]}..."),
|
| 212 |
hotkey=hotkey,
|
| 213 |
status=status,
|
| 214 |
-
|
| 215 |
-
eta=max(int(
|
| 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(
|
| 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 |
-
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
|
| 279 |
-
|
| 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 |
|