Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Provider Inference Metrics Dashboard</title> | |
<!-- Include Plotly.js via CDN --> | |
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script> | |
<style> | |
body { | |
font-family: sans-serif; | |
margin: 20px; | |
background-color: #f4f4f4; | |
} | |
h1 { | |
text-align: center; | |
color: #333; | |
} | |
.dashboard-container { | |
display: grid; | |
grid-template-columns: repeat(auto-fit, minmax(500px, 1fr)); /* Responsive grid */ | |
gap: 20px; /* Space between plots */ | |
padding: 20px; | |
} | |
.plot-container { | |
background-color: #fff; | |
padding: 15px; | |
border-radius: 8px; | |
box-shadow: 0 2px 5px rgba(0,0,0,0.1); | |
min-height: 400px; /* Ensure plots have some height */ | |
} | |
#loading, #error { | |
text-align: center; | |
font-size: 1.2em; | |
padding: 30px; | |
color: #555; | |
} | |
#error { | |
color: red; | |
font-weight: bold; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>Provider Inference Metrics Dashboard</h1> | |
<div id="loading">Loading data... Please wait.</div> | |
<div id="error" style="display: none;"></div> | |
<div class="dashboard-container"> | |
<div id="plotLatencyProvider" class="plot-container"></div> | |
<div id="plotReliabilityProvider" class="plot-container"></div> | |
<div id="plotLatencyModel" class="plot-container"></div> | |
<div id="plotErrorTypesProvider" class="plot-container"></div> | |
<div id="plotLatencyHeatmap" class="plot-container"></div> | |
<!-- Add more divs here for additional plots --> | |
</div> | |
<script> | |
document.addEventListener('DOMContentLoaded', function() { | |
const apiUrl = "https://datasets-server.huggingface.co/rows?dataset=victor%2Fproviders-metrics&config=default&split=train&offset=0&length=1000"; // Fetch 1000 rows | |
const loadingDiv = document.getElementById('loading'); | |
const errorDiv = document.getElementById('error'); | |
const dashboardContainer = document.querySelector('.dashboard-container'); | |
// Initially hide the dashboard container | |
dashboardContainer.style.display = 'none'; | |
fetch(apiUrl) | |
.then(response => { | |
if (!response.ok) { | |
throw new Error(`HTTP error! status: ${response.status}`); | |
} | |
return response.json(); | |
}) | |
.then(data => { | |
loadingDiv.style.display = 'none'; // Hide loading message | |
dashboardContainer.style.display = 'grid'; // Show dashboard | |
// Extract the actual row data | |
const rows = data.rows.map(item => item.row); | |
console.log(`Fetched ${rows.length} rows.`); | |
// --- Data Processing and Plotting --- | |
// 1. Latency by Provider (Box Plot) | |
createLatencyByProviderPlot(rows); | |
// 2. Reliability by Provider (Stacked Bar) | |
createReliabilityByProviderPlot(rows); | |
// 3. Latency by Model (Box Plot) | |
createLatencyByModelPlot(rows); | |
// 4. Error Types by Provider (Grouped Bar) | |
createErrorTypesByProviderPlot(rows); | |
// 5. Latency Heatmap (Model vs Provider) | |
createLatencyHeatmap(rows); | |
}) | |
.catch(error => { | |
console.error('Error fetching or processing data:', error); | |
loadingDiv.style.display = 'none'; | |
errorDiv.textContent = `Error loading data: ${error.message}. Please check the console for details.`; | |
errorDiv.style.display = 'block'; | |
}); | |
// --- Plotting Functions --- | |
function createLatencyByProviderPlot(rows) { | |
const dataByProvider = {}; | |
rows.forEach(row => { | |
if (!dataByProvider[row.provider_name]) { | |
dataByProvider[row.provider_name] = []; | |
} | |
// Only include successful requests or requests with valid duration | |
if (row.duration_ms !== null && row.duration_ms >= 0) { | |
dataByProvider[row.provider_name].push(row.duration_ms); | |
} | |
}); | |
const plotData = Object.keys(dataByProvider).map(provider => ({ | |
y: dataByProvider[provider], | |
type: 'box', | |
name: provider, | |
boxpoints: 'Outliers' // Show outliers | |
})); | |
const layout = { | |
title: 'Latency Distribution by Provider (ms)', | |
yaxis: { title: 'Duration (ms)', type: 'log' }, // Log scale often helps with latency | |
xaxis: { title: 'Provider' }, | |
margin: { l: 50, r: 20, b: 100, t: 50 } // Adjust margins | |
}; | |
Plotly.newPlot('plotLatencyProvider', plotData, layout); | |
} | |
function createReliabilityByProviderPlot(rows) { | |
const statusCountsByProvider = {}; | |
const allProviders = new Set(); | |
const allStatusCodes = new Set(); | |
rows.forEach(row => { | |
const provider = row.provider_name; | |
const status = row.response_status_code; | |
allProviders.add(provider); | |
allStatusCodes.add(status); | |
if (!statusCountsByProvider[provider]) { | |
statusCountsByProvider[provider] = {}; | |
} | |
if (!statusCountsByProvider[provider][status]) { | |
statusCountsByProvider[provider][status] = 0; | |
} | |
statusCountsByProvider[provider][status]++; | |
}); | |
const sortedProviders = Array.from(allProviders).sort(); | |
const sortedStatusCodes = Array.from(allStatusCodes).sort((a, b) => a - b); // Sort numerically | |
const plotData = sortedStatusCodes.map(status => { | |
return { | |
x: sortedProviders, | |
y: sortedProviders.map(provider => statusCountsByProvider[provider]?.[status] || 0), | |
name: `Status ${status}`, | |
type: 'bar' | |
}; | |
}); | |
const layout = { | |
title: 'Request Status Codes by Provider', | |
barmode: 'stack', | |
xaxis: { title: 'Provider' }, | |
yaxis: { title: 'Number of Requests' }, | |
margin: { l: 50, r: 20, b: 100, t: 50 } | |
}; | |
Plotly.newPlot('plotReliabilityProvider', plotData, layout); | |
} | |
function createLatencyByModelPlot(rows) { | |
const dataByModel = {}; | |
rows.forEach(row => { | |
const model = row.model_id; | |
if (!dataByModel[model]) { | |
dataByModel[model] = []; | |
} | |
// Only include successful requests or requests with valid duration | |
if (row.duration_ms !== null && row.duration_ms >= 0) { | |
dataByModel[model].push(row.duration_ms); | |
} | |
}); | |
const plotData = Object.keys(dataByModel).map(model => ({ | |
y: dataByModel[model], | |
type: 'box', | |
name: model, | |
boxpoints: 'Outliers' | |
})); | |
const layout = { | |
title: 'Latency Distribution by Model (ms)', | |
yaxis: { title: 'Duration (ms)', type: 'log' }, | |
xaxis: { | |
title: 'Model ID', | |
tickangle: -45 // Angle labels if they overlap | |
}, | |
margin: { l: 50, r: 20, b: 150, t: 50 } // More bottom margin for angled labels | |
}; | |
Plotly.newPlot('plotLatencyModel', plotData, layout); | |
} | |
function createErrorTypesByProviderPlot(rows) { | |
const errorCountsByProvider = {}; | |
const allProviders = new Set(); | |
const allErrorCodes = new Set(); | |
rows.forEach(row => { | |
if (row.response_status_code !== 200 && row.response_status_code !== null) { // Only errors | |
const provider = row.provider_name; | |
const status = row.response_status_code; | |
allProviders.add(provider); | |
allErrorCodes.add(status); | |
if (!errorCountsByProvider[provider]) { | |
errorCountsByProvider[provider] = {}; | |
} | |
if (!errorCountsByProvider[provider][status]) { | |
errorCountsByProvider[provider][status] = 0; | |
} | |
errorCountsByProvider[provider][status]++; | |
} | |
}); | |
const sortedProviders = Array.from(allProviders).sort(); | |
const sortedErrorCodes = Array.from(allErrorCodes).sort((a, b) => a - b); | |
const plotData = sortedErrorCodes.map(status => { | |
return { | |
x: sortedProviders, | |
y: sortedProviders.map(provider => errorCountsByProvider[provider]?.[status] || 0), | |
name: `Error ${status}`, | |
type: 'bar' | |
}; | |
}); | |
const layout = { | |
title: 'Error Types by Provider (Non-200 Status)', | |
barmode: 'group', // Group bars side-by-side for comparison | |
xaxis: { title: 'Provider' }, | |
yaxis: { title: 'Number of Errors' }, | |
margin: { l: 50, r: 20, b: 100, t: 50 } | |
}; | |
Plotly.newPlot('plotErrorTypesProvider', plotData, layout); | |
} | |
function createLatencyHeatmap(rows) { | |
const latencyData = {}; // { provider: { model: { sum: 0, count: 0 } } } | |
const allProviders = new Set(); | |
const allModels = new Set(); | |
rows.forEach(row => { | |
if (row.duration_ms !== null && row.duration_ms >= 0) { | |
const provider = row.provider_name; | |
const model = row.model_id; | |
allProviders.add(provider); | |
allModels.add(model); | |
if (!latencyData[provider]) latencyData[provider] = {}; | |
if (!latencyData[provider][model]) latencyData[provider][model] = { sum: 0, count: 0 }; | |
latencyData[provider][model].sum += row.duration_ms; | |
latencyData[provider][model].count++; | |
} | |
}); | |
const sortedProviders = Array.from(allProviders).sort(); | |
const sortedModels = Array.from(allModels).sort(); | |
const zValues = sortedModels.map(model => { | |
return sortedProviders.map(provider => { | |
const data = latencyData[provider]?.[model]; | |
return data && data.count > 0 ? data.sum / data.count : null; // Calculate average, handle missing data | |
}); | |
}); | |
const plotData = [{ | |
z: zValues, | |
x: sortedProviders, | |
y: sortedModels, | |
type: 'heatmap', | |
hoverongaps: false, // Don't show tooltips for empty cells | |
colorscale: 'Viridis', // Choose a colorscale | |
colorbar: { title: 'Avg Latency (ms)'} | |
}]; | |
const layout = { | |
title: 'Average Latency (ms) - Model vs. Provider', | |
xaxis: { title: 'Provider', side: 'top' }, // Move x-axis labels to top | |
yaxis: { title: 'Model ID' }, | |
margin: { l: 250, r: 50, b: 50, t: 100 } // Adjust margins for labels | |
}; | |
Plotly.newPlot('plotLatencyHeatmap', plotData, layout); | |
} | |
}); | |
</script> | |
</body> | |
</html> |