Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
Commit
路
17bb6e0
1
Parent(s):
f2a2662
First pass at finetuning api
Browse files
README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
---
|
2 |
-
title:
|
3 |
-
emoji:
|
4 |
colorFrom: purple
|
5 |
colorTo: pink
|
6 |
sdk: gradio
|
|
|
1 |
---
|
2 |
+
title: Finetuning subnet
|
3 |
+
emoji: :em
|
4 |
colorFrom: purple
|
5 |
colorTo: pink
|
6 |
sdk: gradio
|
app.py
CHANGED
@@ -2,6 +2,7 @@
|
|
2 |
|
3 |
import os
|
4 |
import datetime
|
|
|
5 |
import gradio as gr
|
6 |
|
7 |
from dotenv import load_dotenv
|
@@ -13,14 +14,18 @@ import utils
|
|
13 |
FONT = (
|
14 |
"""<link href="https://fonts.cdnfonts.com/css/jmh-typewriter" rel="stylesheet">"""
|
15 |
)
|
16 |
-
TITLE = """<h1 align="center" id="space-title" class="typewriter">Subnet
|
17 |
-
HEADER = """<h2 align="center" class="typewriter"><a href="https://github.com/macrocosm-os/
|
18 |
-
|
19 |
EVALUATION_DETAILS = """<ul><li><b>Name:</b> the 馃 Hugging Face model name (click to go to the model card)</li><li><b>Rewards / Day:</b> the expected rewards per day based on current ranking.</li><li><b>Last Average Loss:</b> the last loss value on the evaluation data for the model as calculated by a validator (lower is better)</li><li><b>UID:</b> the Bittensor UID of the miner</li><li><b>Block:</b> the Bittensor block that the model was submitted in</li></ul><br/>More stats on <a href="https://taostats.io/subnets/netuid-9/" target="_blank">taostats</a>."""
|
20 |
EVALUATION_HEADER = """<h3 align="center">Shows the latest internal evaluation statistics as calculated by the Opentensor validator</h3>"""
|
21 |
|
|
|
|
|
|
|
|
|
22 |
|
23 |
-
HF_REPO_ID = "macrocosm-os/
|
24 |
SECONDS_PER_BLOCK = 12
|
25 |
|
26 |
load_dotenv()
|
@@ -68,6 +73,7 @@ def main():
|
|
68 |
# TODO: Re-enable once ""SubtensorModule.BlocksSinceEpoch" not found" issue is resolved.
|
69 |
# gr.HTML(value=get_next_update_div(current_block, next_epoch_block))
|
70 |
|
|
|
71 |
gr.Label(
|
72 |
value={
|
73 |
f"{c.namespace}/{c.name} ({c.commit[0:8]}) 路 (蟿{round(c.emission, 2):,})": c.incentive
|
@@ -85,19 +91,23 @@ def main():
|
|
85 |
with gr.Accordion("Evaluation Stats"):
|
86 |
gr.HTML(EVALUATION_HEADER)
|
87 |
show_stale = gr.Checkbox(label="Show Stale", interactive=True)
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
|
|
|
|
|
|
|
|
96 |
gr.HTML(EVALUATION_DETAILS)
|
97 |
show_stale.change(
|
98 |
lambda stale: utils.leaderboard_data(model_data, scores, stale),
|
99 |
inputs=[show_stale],
|
100 |
-
outputs=
|
101 |
)
|
102 |
|
103 |
gr.LinePlot(
|
|
|
2 |
|
3 |
import os
|
4 |
import datetime
|
5 |
+
from typing import Dict
|
6 |
import gradio as gr
|
7 |
|
8 |
from dotenv import load_dotenv
|
|
|
14 |
FONT = (
|
15 |
"""<link href="https://fonts.cdnfonts.com/css/jmh-typewriter" rel="stylesheet">"""
|
16 |
)
|
17 |
+
TITLE = """<h1 align="center" id="space-title" class="typewriter">Finetuning Subnet Leaderboard</h1>"""
|
18 |
+
HEADER = """<h2 align="center" class="typewriter"><a href="https://github.com/macrocosm-os/finetuning" target="_blank">Finetuning</a> is a <a href="https://bittensor.com/" target="_blank">Bittensor</a> subnet that rewards miners for producing finetuned models in defined competitions. The model with the best head-to-head score in each competition receive a steady emission of TAO.</h3>"""
|
19 |
+
# TODO: Update links once subnet is regged.
|
20 |
EVALUATION_DETAILS = """<ul><li><b>Name:</b> the 馃 Hugging Face model name (click to go to the model card)</li><li><b>Rewards / Day:</b> the expected rewards per day based on current ranking.</li><li><b>Last Average Loss:</b> the last loss value on the evaluation data for the model as calculated by a validator (lower is better)</li><li><b>UID:</b> the Bittensor UID of the miner</li><li><b>Block:</b> the Bittensor block that the model was submitted in</li></ul><br/>More stats on <a href="https://taostats.io/subnets/netuid-9/" target="_blank">taostats</a>."""
|
21 |
EVALUATION_HEADER = """<h3 align="center">Shows the latest internal evaluation statistics as calculated by the Opentensor validator</h3>"""
|
22 |
|
23 |
+
# A map of competition IDs to HTML descriptions.
|
24 |
+
COMPETITION_DETAILS: Dict[int, str] = {
|
25 |
+
1: """<b>Competition ID 1:</b> Produce the best fine-tuned model from a Subnet 9 pretrained model. Models are evaluated using synthetic prompt/response data from Subnet 18."""
|
26 |
+
}
|
27 |
|
28 |
+
HF_REPO_ID = "macrocosm-os/finetuning-leaderboard"
|
29 |
SECONDS_PER_BLOCK = 12
|
30 |
|
31 |
load_dotenv()
|
|
|
73 |
# TODO: Re-enable once ""SubtensorModule.BlocksSinceEpoch" not found" issue is resolved.
|
74 |
# gr.HTML(value=get_next_update_div(current_block, next_epoch_block))
|
75 |
|
76 |
+
# TODO: Figure out the best approach to showing the per competition rewards.
|
77 |
gr.Label(
|
78 |
value={
|
79 |
f"{c.namespace}/{c.name} ({c.commit[0:8]}) 路 (蟿{round(c.emission, 2):,})": c.incentive
|
|
|
91 |
with gr.Accordion("Evaluation Stats"):
|
92 |
gr.HTML(EVALUATION_HEADER)
|
93 |
show_stale = gr.Checkbox(label="Show Stale", interactive=True)
|
94 |
+
competition_leaderboards = []
|
95 |
+
# TODO: Dynamically generate per-competition leaderboards based on model_data.
|
96 |
+
with gr.Accordion("Finetuned SN9 competition"):
|
97 |
+
gr.HTML(COMPETITION_DETAILS[1])
|
98 |
+
competition_leaderboards.append(gr.components.Dataframe(
|
99 |
+
value=utils.leaderboard_data(model_data, scores, show_stale.value),
|
100 |
+
headers=["Name", "Win Rate", "Average Loss", "Weight", "UID", "Block"],
|
101 |
+
datatype=["markdown", "number", "number", "number", "number", "number"],
|
102 |
+
elem_id="leaderboard-table",
|
103 |
+
interactive=False,
|
104 |
+
visible=True,
|
105 |
+
))
|
106 |
gr.HTML(EVALUATION_DETAILS)
|
107 |
show_stale.change(
|
108 |
lambda stale: utils.leaderboard_data(model_data, scores, stale),
|
109 |
inputs=[show_stale],
|
110 |
+
outputs=competition_leaderboards,
|
111 |
)
|
112 |
|
113 |
gr.LinePlot(
|
utils.py
CHANGED
@@ -148,9 +148,10 @@ def get_subnet_data(
|
|
148 |
|
149 |
def get_wandb_runs(project: str, filters: Dict[str, Any]) -> List:
|
150 |
"""Get the latest runs from Wandb, retrying infinitely until we get them.
|
151 |
-
|
152 |
Returns:
|
153 |
-
List: List of runs matching the provided filters, newest run (by creation time) first.
|
|
|
154 |
while True:
|
155 |
api = wandb.Api(api_key=WANDB_TOKEN)
|
156 |
runs = list(
|
@@ -172,7 +173,7 @@ def get_scores(
|
|
172 |
wandb_runs: List,
|
173 |
) -> Dict[int, Dict[str, Optional[float]]]:
|
174 |
"""Returns the most recent scores for the provided UIDs.
|
175 |
-
|
176 |
Args:
|
177 |
uids (List[int]): List of UIDs to get scores for.
|
178 |
wandb_runs (List): List of validator runs from Wandb. Requires the runs are provided in descending order.
|
@@ -204,6 +205,7 @@ def get_scores(
|
|
204 |
"win_rate": uid_data.get("win_rate", None),
|
205 |
"win_total": uid_data.get("win_total", None),
|
206 |
"weight": uid_data.get("weight", None),
|
|
|
207 |
"fresh": is_fresh,
|
208 |
}
|
209 |
if len(result) == len(uids):
|
@@ -244,12 +246,7 @@ def get_losses_over_time(wandb_runs: List) -> pd.DataFrame:
|
|
244 |
best_loss = math.inf
|
245 |
for _, uid_data in all_uid_data.items():
|
246 |
loss = uid_data.get("average_loss", math.inf)
|
247 |
-
|
248 |
-
if (
|
249 |
-
loss < best_loss
|
250 |
-
and (loss > 2.5 or timestamp > datetime.datetime(2024, 2, 12))
|
251 |
-
and (loss < 5 or timestamp > datetime.datetime(2024, 3, 27))
|
252 |
-
):
|
253 |
best_loss = uid_data["average_loss"]
|
254 |
if best_loss != math.inf:
|
255 |
timestamps.append(timestamp)
|
@@ -386,6 +383,7 @@ def load_state_vars() -> dict[Any]:
|
|
386 |
bt.logging.success(f"Loaded {len(model_data)} models")
|
387 |
vali_runs = get_wandb_runs(
|
388 |
project=VALIDATOR_WANDB_PROJECT,
|
|
|
389 |
filters={"config.type": "validator", "config.uid": 238},
|
390 |
)
|
391 |
|
@@ -427,7 +425,7 @@ def load_state_vars() -> dict[Any]:
|
|
427 |
|
428 |
|
429 |
def test_load_state_vars():
|
430 |
-
|
431 |
subtensor = bt.subtensor("finney")
|
432 |
metagraph = subtensor.metagraph(NETUID, lite=True)
|
433 |
model_data = [
|
|
|
148 |
|
149 |
def get_wandb_runs(project: str, filters: Dict[str, Any]) -> List:
|
150 |
"""Get the latest runs from Wandb, retrying infinitely until we get them.
|
151 |
+
|
152 |
Returns:
|
153 |
+
List: List of runs matching the provided filters, newest run (by creation time) first.
|
154 |
+
"""
|
155 |
while True:
|
156 |
api = wandb.Api(api_key=WANDB_TOKEN)
|
157 |
runs = list(
|
|
|
173 |
wandb_runs: List,
|
174 |
) -> Dict[int, Dict[str, Optional[float]]]:
|
175 |
"""Returns the most recent scores for the provided UIDs.
|
176 |
+
|
177 |
Args:
|
178 |
uids (List[int]): List of UIDs to get scores for.
|
179 |
wandb_runs (List): List of validator runs from Wandb. Requires the runs are provided in descending order.
|
|
|
205 |
"win_rate": uid_data.get("win_rate", None),
|
206 |
"win_total": uid_data.get("win_total", None),
|
207 |
"weight": uid_data.get("weight", None),
|
208 |
+
"competition_id": uid_data.get("competition_id", None),
|
209 |
"fresh": is_fresh,
|
210 |
}
|
211 |
if len(result) == len(uids):
|
|
|
246 |
best_loss = math.inf
|
247 |
for _, uid_data in all_uid_data.items():
|
248 |
loss = uid_data.get("average_loss", math.inf)
|
249 |
+
if loss < best_loss:
|
|
|
|
|
|
|
|
|
|
|
250 |
best_loss = uid_data["average_loss"]
|
251 |
if best_loss != math.inf:
|
252 |
timestamps.append(timestamp)
|
|
|
383 |
bt.logging.success(f"Loaded {len(model_data)} models")
|
384 |
vali_runs = get_wandb_runs(
|
385 |
project=VALIDATOR_WANDB_PROJECT,
|
386 |
+
# TODO: Update to point to the OTF vali on finetuning
|
387 |
filters={"config.type": "validator", "config.uid": 238},
|
388 |
)
|
389 |
|
|
|
425 |
|
426 |
|
427 |
def test_load_state_vars():
|
428 |
+
# TODO: Change to finetuning data.
|
429 |
subtensor = bt.subtensor("finney")
|
430 |
metagraph = subtensor.metagraph(NETUID, lite=True)
|
431 |
model_data = [
|