Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -4,12 +4,12 @@ Streamlit dashboard for the Dippy Roleplay Subnet Leaderboard
|
|
| 4 |
import requests
|
| 5 |
import streamlit as st
|
| 6 |
import pandas as pd
|
|
|
|
| 7 |
|
| 8 |
st.set_page_config(layout="wide")
|
| 9 |
|
| 10 |
-
import pandas as pd
|
| 11 |
-
import numpy as np
|
| 12 |
REMOTE_LEADERBOARD_URL = "https://dippy-bittensor-subnet.com/minerboard"
|
|
|
|
| 13 |
def iswin(score_i, score_j, block_i, block_j):
|
| 14 |
MAX_PENALTY = 0.03 # Adjust this value as needed
|
| 15 |
penalty = MAX_PENALTY
|
|
@@ -30,7 +30,32 @@ def calculate_win_rate(df):
|
|
| 30 |
|
| 31 |
return win_counts / (n - 1) # Divide by (n-1) as each row isn't compared with itself
|
| 32 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 33 |
|
|
|
|
|
|
|
| 34 |
|
| 35 |
def leaderboard_dashboard():
|
| 36 |
# load the logo from image.txt file as base64
|
|
@@ -48,7 +73,6 @@ def leaderboard_dashboard():
|
|
| 48 |
unsafe_allow_html=True,
|
| 49 |
)
|
| 50 |
|
| 51 |
-
|
| 52 |
# Add emojis based on the status
|
| 53 |
status_emojis = {
|
| 54 |
'COMPLETED': '✅COMPLETED',
|
|
@@ -56,10 +80,8 @@ def leaderboard_dashboard():
|
|
| 56 |
'QUEUED': '🕒QUEUED',
|
| 57 |
'RUNNING': '🏃RUNNING'
|
| 58 |
}
|
| 59 |
-
|
| 60 |
|
| 61 |
# Get the minerboard data from the API
|
| 62 |
-
# response = requests.get("http://34.41.206.211:8000/minerboard")
|
| 63 |
response = requests.get(REMOTE_LEADERBOARD_URL)
|
| 64 |
if response.status_code != 200:
|
| 65 |
st.error("Failed to fetch minerboard data.")
|
|
@@ -67,39 +89,50 @@ def leaderboard_dashboard():
|
|
| 67 |
|
| 68 |
# Parse the response JSON data
|
| 69 |
minerboard_data = response.json()
|
|
|
|
| 70 |
# Convert the data to a DataFrame
|
| 71 |
minerboard = pd.DataFrame(minerboard_data)
|
|
|
|
| 72 |
# Set FAILED entries to have total_score as 0
|
| 73 |
minerboard.loc[minerboard['status'] == 'FAILED', 'total_score'] = 0
|
| 74 |
-
|
|
|
|
|
|
|
|
|
|
| 75 |
minerboard['status'] = minerboard['status'].map(lambda status: status_emojis.get(status, status))
|
| 76 |
-
|
|
|
|
| 77 |
minerboard = minerboard.sort_values(by='total_score', ascending=False, ignore_index=True)
|
| 78 |
|
| 79 |
front_order = ['uid', 'hotkey', 'total_score', 'status', 'chat_template_type', 'hash']
|
|
|
|
|
|
|
| 80 |
|
| 81 |
# move status column to the front
|
| 82 |
column_order = front_order + [column for column in minerboard.columns if column not in front_order]
|
| 83 |
-
|
| 84 |
minerboard = minerboard[column_order]
|
| 85 |
|
| 86 |
-
|
| 87 |
minerboard_winrate = pd.DataFrame(minerboard_data)
|
| 88 |
-
|
| 89 |
-
|
| 90 |
minerboard_winrate.loc[minerboard_winrate['status'] == 'FAILED', 'total_score'] = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
minerboard_winrate['status'] = minerboard_winrate['status'].map(lambda status: status_emojis.get(status, status))
|
| 92 |
-
|
| 93 |
minerboard_winrate['win_rate'] = calculate_win_rate(minerboard_winrate)
|
| 94 |
-
|
| 95 |
minerboard_winrate = minerboard_winrate.sort_values(by='win_rate', ascending=False, ignore_index=True)
|
| 96 |
|
| 97 |
-
column_order = ['uid', 'win_rate', 'hotkey', 'repo_namespace', 'repo_name', 'total_score', 'block', 'judge_score'
|
| 98 |
-
|
|
|
|
|
|
|
| 99 |
# Create a new DataFrame with only the specified columns
|
| 100 |
minerboard_winrate = minerboard_winrate[column_order]
|
| 101 |
-
|
|
|
|
| 102 |
st.dataframe(minerboard_winrate, hide_index=True)
|
|
|
|
| 103 |
with st.expander("See detailed calculation method"):
|
| 104 |
st.write("The win rate is calculated by comparing each miner against every other miner. Note that this board is only an approximation as queued miners have a score of 0, validators are omitted, etc.")
|
| 105 |
st.code("""
|
|
@@ -110,11 +143,17 @@ def leaderboard_dashboard():
|
|
| 110 |
score_j = (1 - penalty) * score_j if block_j > block_i else score_j
|
| 111 |
return score_i > score_j
|
| 112 |
""")
|
|
|
|
| 113 |
st.markdown("---")
|
|
|
|
| 114 |
st.header("Minerboard")
|
| 115 |
st.dataframe(minerboard, hide_index=True)
|
|
|
|
| 116 |
st.markdown("---")
|
|
|
|
|
|
|
|
|
|
| 117 |
|
| 118 |
|
| 119 |
if __name__ == '__main__':
|
| 120 |
-
leaderboard_dashboard()
|
|
|
|
| 4 |
import requests
|
| 5 |
import streamlit as st
|
| 6 |
import pandas as pd
|
| 7 |
+
import numpy as np
|
| 8 |
|
| 9 |
st.set_page_config(layout="wide")
|
| 10 |
|
|
|
|
|
|
|
| 11 |
REMOTE_LEADERBOARD_URL = "https://dippy-bittensor-subnet.com/minerboard"
|
| 12 |
+
|
| 13 |
def iswin(score_i, score_j, block_i, block_j):
|
| 14 |
MAX_PENALTY = 0.03 # Adjust this value as needed
|
| 15 |
penalty = MAX_PENALTY
|
|
|
|
| 30 |
|
| 31 |
return win_counts / (n - 1) # Divide by (n-1) as each row isn't compared with itself
|
| 32 |
|
| 33 |
+
def apply_block_threshold_mutation(df, block_threshold):
|
| 34 |
+
"""
|
| 35 |
+
Apply mutation to rows where block is less than the threshold.
|
| 36 |
+
Changes total_score, judge_score, and notes columns for these rows.
|
| 37 |
+
|
| 38 |
+
Args:
|
| 39 |
+
df: DataFrame to modify
|
| 40 |
+
block_threshold: Rows with block value less than this will be modified
|
| 41 |
+
|
| 42 |
+
Returns:
|
| 43 |
+
Modified DataFrame
|
| 44 |
+
"""
|
| 45 |
+
# Create a copy to avoid modifying the original DataFrame
|
| 46 |
+
modified_df = df.copy()
|
| 47 |
+
|
| 48 |
+
# Identify rows where block is less than the threshold
|
| 49 |
+
mask = modified_df['block'] < block_threshold
|
| 50 |
+
|
| 51 |
+
# Apply mutations to these rows
|
| 52 |
+
if mask.any():
|
| 53 |
+
modified_df.loc[mask, 'total_score'] = 0.0 # Set total_score to 0
|
| 54 |
+
modified_df.loc[mask, 'judge_score'] = 0.0 # Set judge_score to 0
|
| 55 |
+
modified_df.loc[mask, 'notes'] = "Scoring reset"
|
| 56 |
|
| 57 |
+
|
| 58 |
+
return modified_df
|
| 59 |
|
| 60 |
def leaderboard_dashboard():
|
| 61 |
# load the logo from image.txt file as base64
|
|
|
|
| 73 |
unsafe_allow_html=True,
|
| 74 |
)
|
| 75 |
|
|
|
|
| 76 |
# Add emojis based on the status
|
| 77 |
status_emojis = {
|
| 78 |
'COMPLETED': '✅COMPLETED',
|
|
|
|
| 80 |
'QUEUED': '🕒QUEUED',
|
| 81 |
'RUNNING': '🏃RUNNING'
|
| 82 |
}
|
|
|
|
| 83 |
|
| 84 |
# Get the minerboard data from the API
|
|
|
|
| 85 |
response = requests.get(REMOTE_LEADERBOARD_URL)
|
| 86 |
if response.status_code != 200:
|
| 87 |
st.error("Failed to fetch minerboard data.")
|
|
|
|
| 89 |
|
| 90 |
# Parse the response JSON data
|
| 91 |
minerboard_data = response.json()
|
| 92 |
+
|
| 93 |
# Convert the data to a DataFrame
|
| 94 |
minerboard = pd.DataFrame(minerboard_data)
|
| 95 |
+
|
| 96 |
# Set FAILED entries to have total_score as 0
|
| 97 |
minerboard.loc[minerboard['status'] == 'FAILED', 'total_score'] = 0
|
| 98 |
+
block_threshold = 5207777
|
| 99 |
+
# Apply block threshold mutation
|
| 100 |
+
minerboard = apply_block_threshold_mutation(minerboard, block_threshold)
|
| 101 |
+
|
| 102 |
minerboard['status'] = minerboard['status'].map(lambda status: status_emojis.get(status, status))
|
| 103 |
+
|
| 104 |
+
# Sort the minerboard by the total_score column
|
| 105 |
minerboard = minerboard.sort_values(by='total_score', ascending=False, ignore_index=True)
|
| 106 |
|
| 107 |
front_order = ['uid', 'hotkey', 'total_score', 'status', 'chat_template_type', 'hash']
|
| 108 |
+
if 'notes' in minerboard.columns:
|
| 109 |
+
front_order.append('notes')
|
| 110 |
|
| 111 |
# move status column to the front
|
| 112 |
column_order = front_order + [column for column in minerboard.columns if column not in front_order]
|
|
|
|
| 113 |
minerboard = minerboard[column_order]
|
| 114 |
|
| 115 |
+
# Win rate calculation
|
| 116 |
minerboard_winrate = pd.DataFrame(minerboard_data)
|
|
|
|
|
|
|
| 117 |
minerboard_winrate.loc[minerboard_winrate['status'] == 'FAILED', 'total_score'] = 0
|
| 118 |
+
|
| 119 |
+
# Apply block threshold mutation to winrate dataframe too
|
| 120 |
+
minerboard_winrate = apply_block_threshold_mutation(minerboard_winrate, block_threshold)
|
| 121 |
+
|
| 122 |
minerboard_winrate['status'] = minerboard_winrate['status'].map(lambda status: status_emojis.get(status, status))
|
|
|
|
| 123 |
minerboard_winrate['win_rate'] = calculate_win_rate(minerboard_winrate)
|
|
|
|
| 124 |
minerboard_winrate = minerboard_winrate.sort_values(by='win_rate', ascending=False, ignore_index=True)
|
| 125 |
|
| 126 |
+
column_order = ['uid', 'win_rate', 'hotkey', 'repo_namespace', 'repo_name', 'total_score', 'block', 'judge_score']
|
| 127 |
+
if 'notes' in minerboard_winrate.columns:
|
| 128 |
+
column_order.append('notes')
|
| 129 |
+
|
| 130 |
# Create a new DataFrame with only the specified columns
|
| 131 |
minerboard_winrate = minerboard_winrate[column_order]
|
| 132 |
+
|
| 133 |
+
st.header("Leaderboard by Win Rate")
|
| 134 |
st.dataframe(minerboard_winrate, hide_index=True)
|
| 135 |
+
|
| 136 |
with st.expander("See detailed calculation method"):
|
| 137 |
st.write("The win rate is calculated by comparing each miner against every other miner. Note that this board is only an approximation as queued miners have a score of 0, validators are omitted, etc.")
|
| 138 |
st.code("""
|
|
|
|
| 143 |
score_j = (1 - penalty) * score_j if block_j > block_i else score_j
|
| 144 |
return score_i > score_j
|
| 145 |
""")
|
| 146 |
+
|
| 147 |
st.markdown("---")
|
| 148 |
+
|
| 149 |
st.header("Minerboard")
|
| 150 |
st.dataframe(minerboard, hide_index=True)
|
| 151 |
+
|
| 152 |
st.markdown("---")
|
| 153 |
+
|
| 154 |
+
if block_threshold > 0:
|
| 155 |
+
st.info(f"Note: Entries with block values below {block_threshold} have had their scores set to 0.")
|
| 156 |
|
| 157 |
|
| 158 |
if __name__ == '__main__':
|
| 159 |
+
leaderboard_dashboard()
|