Add leaderboards

This commit is contained in:
Ethan 2024-12-27 18:16:50 -05:00
parent 90b7511426
commit 2feaf8f3ad
7 changed files with 148 additions and 27 deletions

View File

@ -64,8 +64,8 @@ impl Groq {
},
}],
usage: ChatCompletionUsage {
total_tokens: 0,
total_time: 0.0,
total_tokens: -1,
total_time: -1.0,
},
};

View File

@ -4,6 +4,7 @@ pub mod model_response;
pub mod model_selection;
pub mod prompt_input;
pub mod state;
pub mod leaderboard;
pub fn main(models_available: Vec<String>) -> eframe::Result {
let options = eframe::NativeOptions {

View File

@ -0,0 +1,110 @@
use eframe::egui::{self, Response, Ui, Widget};
use super::state::AppState;
pub struct Leaderboard {
entries: Vec<LeaderboardEntry>,
}
#[derive(Clone)]
struct LeaderboardEntry {
name: String,
tokens: i32,
time: f32,
}
impl Leaderboard {
pub fn new(app_state: &AppState) -> Self {
let entries = app_state
.selected_models
.iter()
.map(|model| LeaderboardEntry {
name: model.name.clone(),
tokens: model.tokens,
time: model.time,
})
.collect();
Self { entries }
}
}
impl Widget for Leaderboard {
fn ui(self, ui: &mut Ui) -> Response {
let leaderboard_gap = 8.0;
let mut time_leaderboard = self.entries.clone();
time_leaderboard.sort_by(|a, b| {
a.time
.partial_cmp(&b.time)
.unwrap_or(std::cmp::Ordering::Equal)
});
let mut tokens_leaderboard = self.entries.clone();
tokens_leaderboard.sort_by(|a, b| {
b.tokens
.partial_cmp(&a.tokens)
.unwrap_or(std::cmp::Ordering::Equal)
});
let mut time_per_token_leaderboard = self.entries.clone();
time_per_token_leaderboard.sort_by(|a, b| {
(a.time / a.tokens as f32)
.partial_cmp(&(b.time / b.tokens as f32))
.unwrap_or(std::cmp::Ordering::Equal)
});
ui.vertical(|ui| {
ui.heading("Leaderboard");
ui.horizontal_top(|ui| {
egui::Grid::new("time_leaderboard")
.striped(true)
.show(ui, |ui| {
ui.strong("Name");
ui.strong("Time");
ui.end_row();
for entry in time_leaderboard {
ui.label(entry.name);
ui.label(entry.time.to_string());
ui.end_row();
}
});
ui.allocate_space(egui::Vec2::new(leaderboard_gap, 0.0));
egui::Grid::new("tokens_leaderboard")
.striped(true)
.show(ui, |ui| {
ui.strong("Name");
ui.strong("Tokens");
ui.end_row();
for entry in tokens_leaderboard {
ui.label(entry.name);
ui.label(entry.tokens.to_string());
ui.end_row();
}
});
ui.allocate_space(egui::Vec2::new(leaderboard_gap, 0.0));
egui::Grid::new("time_per_token_leaderboard")
.striped(true)
.show(ui, |ui| {
ui.strong("Name");
ui.strong("Time per Token");
ui.end_row();
for entry in time_per_token_leaderboard {
ui.label(entry.name);
ui.label((entry.time / entry.tokens as f32).to_string());
ui.end_row();
}
});
})
})
.response
}
}

View File

@ -6,8 +6,8 @@ use crate::groq::{types::ChatCompletionResponse, GROQ_CLIENT};
pub struct ModelResponse {
pub name: String,
message: String,
tokens: i32,
time: f32,
pub tokens: i32,
pub time: f32,
loading: bool,
tx: Sender<ChatCompletionResponse>,
rx: Receiver<ChatCompletionResponse>,
@ -45,7 +45,11 @@ impl ModelResponse {
}
}
fn spawn_chat_completion_task(prompt: String, model_name: String, tx: Sender<ChatCompletionResponse>) {
fn spawn_chat_completion_task(
prompt: String,
model_name: String,
tx: Sender<ChatCompletionResponse>,
) {
tokio::spawn(async move {
let response = GROQ_CLIENT.chat_completion(model_name, prompt).await;
tx.send(response).expect("Failed to send response");
@ -65,7 +69,7 @@ impl Widget for &mut ModelResponse {
.rounding(4.0)
.fill(egui::Color32::DARK_GRAY)
.show(ui, |ui| {
ui.label(RichText::new(&self.name).strong());
ui.label(RichText::new(&self.name).strong().heading());
ui.horizontal_wrapped(|ui| {
ui.horizontal(|ui| {

View File

@ -14,9 +14,10 @@ impl<'a> ModelSelection<'a> {
impl<'a> Widget for ModelSelection<'a> {
fn ui(self, ui: &mut Ui) -> Response {
ui.heading("Models");
ui.horizontal(|ui| {
egui::ComboBox::from_label("")
.selected_text("Models")
.selected_text("Model List")
.show_ui(ui, |ui| {
for model in &self.app_state.models_available {
let selected_models = self

View File

@ -14,22 +14,23 @@ impl<'a> PromptInput<'a> {
impl<'a> Widget for PromptInput<'a> {
fn ui(self, ui: &mut Ui) -> Response {
let label = ui.label("Prompt:");
ui.add_sized(
Vec2::new(ui.available_width(), 100.0),
TextEdit::multiline(&mut self.app_state.prompt_input),
)
.labelled_by(label.id);
ui.vertical(|ui| {
let label = ui.heading("Prompt");
ui.add_sized(
Vec2::new(ui.available_width() / 2.0, 100.0),
TextEdit::multiline(&mut self.app_state.prompt_input),
)
.labelled_by(label.id);
ui.horizontal(|ui| {
if ui.button("Submit").clicked() {
self.app_state.handle_submission();
}
ui.horizontal(|ui| {
if ui.button("Submit").clicked() {
self.app_state.handle_submission();
}
if ui.button("Clear").clicked() {
self.app_state.prompt_input.clear();
}
})
.response
if ui.button("Clear").clicked() {
self.app_state.prompt_input.clear();
}
})
}).response
}
}

View File

@ -3,7 +3,7 @@ use eframe::{
CreationContext,
};
use super::{model_response::ModelResponse, model_selection, prompt_input};
use super::{leaderboard, model_response::ModelResponse, model_selection, prompt_input};
pub struct AppState {
pub selected_models: Vec<ModelResponse>,
@ -30,12 +30,16 @@ impl AppState {
impl eframe::App for AppState {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.heading("Groq Model Comparison");
ui.label("Compare Groq models with ease!");
ui.add(model_selection::ModelSelection::new(self));
ui.add(prompt_input::PromptInput::new(self));
ui.allocate_space(egui::Vec2::new(0.0, 8.0));
ui.horizontal(|ui| {
ui.add(prompt_input::PromptInput::new(self));
ui.allocate_space(egui::Vec2::new(16.0, 0.0));
ui.add(leaderboard::Leaderboard::new(self));
});
ui.add(Separator::default().spacing(16.0));