| | import json |
| | import logging |
| | import pathlib |
| | import pandas as pd |
| | import gradio as gr |
| | import schedule |
| | import time |
| | from datetime import datetime, timezone |
| |
|
| | from src.envs import API |
| |
|
| | |
| | logging.basicConfig(level=logging.INFO) |
| | logger = logging.getLogger(__name__) |
| |
|
| | class VoteManager: |
| | def __init__(self, votes_path, eval_requests_path, repo_id): |
| | self.votes_path = votes_path |
| | self.eval_requests_path = eval_requests_path |
| | self.repo_id = repo_id |
| | self.vote_dataset = self.read_vote_dataset() |
| | self.vote_check_set = self.make_check_set(self.vote_dataset) |
| | self.votes_to_upload = [] |
| |
|
| | def init_vote_dataset(self): |
| | self.vote_dataset = self.read_vote_dataset() |
| | self.vote_check_set = self.make_check_set(self.vote_dataset) |
| |
|
| | def read_vote_dataset(self): |
| | result = [] |
| | votes_file = pathlib.Path(self.votes_path) / "votes_data.jsonl" |
| | if votes_file.exists(): |
| | with open(votes_file, "r") as f: |
| | for line in f: |
| | data = json.loads(line.strip()) |
| | result.append(data) |
| | result = pd.DataFrame(result) |
| | return result |
| |
|
| | def make_check_set(self, vote_dataset: pd.DataFrame): |
| | result = list() |
| | for row in vote_dataset.itertuples(index=False, name='vote'): |
| | result.append((row.model, row.revision, row.username)) |
| | return set(result) |
| | |
| | def get_model_revision(self, selected_model: str) -> str: |
| | """Fetch the revision for the given model from the request files.""" |
| | for user_folder in pathlib.Path(self.eval_requests_path).iterdir(): |
| | if user_folder.is_dir(): |
| | for file in user_folder.glob("*.json"): |
| | with open(file, "r") as f: |
| | data = json.load(f) |
| | if data.get("model") == selected_model: |
| | return data.get("revision", "main") |
| | return "main" |
| |
|
| | def create_request_vote_df(self, pending_models_df: gr.Dataframe): |
| | if pending_models_df.empty or not "model_name" in pending_models_df.columns: |
| | return pending_models_df |
| | self.vote_dataset = self.read_vote_dataset() |
| | vote_counts = self.vote_dataset.groupby(['model', 'revision']).size().reset_index(name='vote_count') |
| |
|
| | pending_models_df_votes = pd.merge( |
| | pending_models_df, |
| | vote_counts, |
| | left_on=["model_name", 'revision'], |
| | right_on=['model', 'revision'], |
| | how='left' |
| | ) |
| | |
| | pending_models_df_votes['vote_count'] = pending_models_df_votes['vote_count'].fillna(0) |
| | pending_models_df_votes = pending_models_df_votes.sort_values(by=["vote_count", "model_name"], ascending=[False, True]) |
| | |
| | pending_models_df_votes = pending_models_df_votes.drop(["model_name", "model"], axis=1) |
| | return pending_models_df_votes |
| |
|
| | |
| | def add_vote( |
| | self, |
| | selected_model: str, |
| | pending_models_df: gr.Dataframe, |
| | profile: gr.OAuthProfile | None |
| | ): |
| | logger.debug(f"Type of list before usage: {type(list)}") |
| | |
| | if selected_model in ["str", ""]: |
| | gr.Warning("No model selected") |
| | return |
| | |
| | if profile is None: |
| | gr.Warning("Hub Login required") |
| | return |
| |
|
| | vote_username = profile.username |
| | model_revision = self.get_model_revision(selected_model) |
| | |
| | |
| | check_tuple = (selected_model, model_revision, vote_username) |
| | if check_tuple in self.vote_check_set: |
| | gr.Warning("Already voted for this model") |
| | return |
| | |
| | current_time = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") |
| |
|
| | vote_obj = { |
| | "model": selected_model, |
| | "revision": model_revision, |
| | "username": vote_username, |
| | "timestamp": current_time |
| | } |
| |
|
| | |
| | try: |
| | votes_file = pathlib.Path(self.votes_path) / "votes_data.jsonl" |
| | with open(votes_file, "a") as f: |
| | f.write(json.dumps(vote_obj) + "\n") |
| | logger.info(f"Vote added locally: {vote_obj}") |
| |
|
| | self.votes_to_upload.append(vote_obj) |
| | except Exception as e: |
| | logger.error(f"Failed to write vote to file: {e}") |
| | gr.Warning("Failed to record vote. Please try again") |
| | return |
| | |
| | self.vote_check_set.add(check_tuple) |
| | gr.Info(f"Voted for {selected_model}") |
| |
|
| | return self.create_request_vote_df(pending_models_df) |
| |
|
| | def upload_votes(self): |
| | if self.votes_to_upload: |
| | votes_file = pathlib.Path(self.votes_path) / "votes_data.jsonl" |
| | try: |
| | with open(votes_file, "rb") as f: |
| | API.upload_file( |
| | path_or_fileobj=f, |
| | path_in_repo="votes_data.jsonl", |
| | repo_id=self.repo_id, |
| | repo_type="dataset", |
| | commit_message="Updating votes_data.jsonl with new votes", |
| | ) |
| | logger.info("Votes uploaded to votes repository") |
| | self.votes_to_upload.clear() |
| | except Exception as e: |
| | logger.error(f"Failed to upload votes to repository: {e}") |
| |
|
| | def run_scheduler(vote_manager): |
| | while True: |
| | schedule.run_pending() |
| | time.sleep(1) |
| |
|