Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import pandas as pd | |
| from datetime import datetime | |
| import difflib | |
| import json | |
| def fetch_model_versions(repo_id): | |
| """ | |
| Fetch model versions from the Hugging Face API. | |
| In a real implementation, this would call the HF API to get version history. | |
| For now, we'll use demo data. | |
| """ | |
| # In a production app, you would fetch this from the Hugging Face API | |
| # For demo purposes, create some sample version data | |
| versions = [ | |
| { | |
| "version": "v1.0", | |
| "commit_id": "abc123", | |
| "timestamp": "2023-01-15T10:30:00Z", | |
| "author": st.session_state.username, | |
| "message": "Initial model release", | |
| "files_changed": 5, | |
| "performance": {"accuracy": 0.85, "f1": 0.82} | |
| }, | |
| { | |
| "version": "v1.1", | |
| "commit_id": "def456", | |
| "timestamp": "2023-02-20T14:45:00Z", | |
| "author": st.session_state.username, | |
| "message": "Improved tokenization", | |
| "files_changed": 2, | |
| "performance": {"accuracy": 0.87, "f1": 0.84} | |
| }, | |
| { | |
| "version": "v2.0", | |
| "commit_id": "ghi789", | |
| "timestamp": "2023-03-10T09:15:00Z", | |
| "author": st.session_state.username, | |
| "message": "Major model architecture upgrade", | |
| "files_changed": 12, | |
| "performance": {"accuracy": 0.92, "f1": 0.90} | |
| } | |
| ] | |
| return versions | |
| def render_version_history(model_info): | |
| """Render the version history of a model""" | |
| if not model_info: | |
| st.error("Model information not found") | |
| return | |
| repo_id = model_info.modelId | |
| st.subheader("π Version History") | |
| with st.spinner("Loading version history..."): | |
| versions = fetch_model_versions(repo_id) | |
| if not versions: | |
| st.info("No version history found for this model.") | |
| return | |
| # Convert to DataFrame for easier display | |
| df = pd.DataFrame(versions) | |
| # Format timestamp | |
| df["timestamp"] = pd.to_datetime(df["timestamp"]).dt.strftime("%Y-%m-%d %H:%M") | |
| # Create a cleaner display version | |
| display_df = df[["version", "timestamp", "author", "message", "files_changed"]] | |
| display_df.columns = ["Version", "Date", "Author", "Commit Message", "Files Changed"] | |
| # Show the version history | |
| st.dataframe(display_df, use_container_width=True) | |
| # Version comparison | |
| st.subheader("Compare Versions") | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| base_version = st.selectbox( | |
| "Base Version", | |
| options=df["version"].tolist(), | |
| index=0 | |
| ) | |
| with col2: | |
| compare_version = st.selectbox( | |
| "Compare Version", | |
| options=[v for v in df["version"].tolist() if v != base_version], | |
| index=0 | |
| ) | |
| if st.button("Compare", use_container_width=True): | |
| with st.spinner("Generating comparison..."): | |
| # In a real implementation, fetch the actual data from each version | |
| # For demo, use the sample performance metrics | |
| base_data = df[df["version"] == base_version].iloc[0] | |
| compare_data = df[df["version"] == compare_version].iloc[0] | |
| # Display comparison | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| st.markdown(f"### {base_version}") | |
| st.markdown(f"**Commit:** {base_data['commit_id']}") | |
| st.markdown(f"**Date:** {base_data['timestamp']}") | |
| st.markdown(f"**Author:** {base_data['author']}") | |
| st.markdown(f"**Message:** {base_data['message']}") | |
| # Performance metrics | |
| st.markdown("#### Performance Metrics") | |
| for metric, value in base_data["performance"].items(): | |
| st.markdown(f"**{metric.capitalize()}:** {value:.4f}") | |
| with col2: | |
| st.markdown(f"### {compare_version}") | |
| st.markdown(f"**Commit:** {compare_data['commit_id']}") | |
| st.markdown(f"**Date:** {compare_data['timestamp']}") | |
| st.markdown(f"**Author:** {compare_data['author']}") | |
| st.markdown(f"**Message:** {compare_data['message']}") | |
| # Performance metrics | |
| st.markdown("#### Performance Metrics") | |
| for metric, value in compare_data["performance"].items(): | |
| # Calculate change | |
| base_value = base_data["performance"].get(metric, 0) | |
| change = value - base_value | |
| change_pct = (change / base_value * 100) if base_value != 0 else float('inf') | |
| # Display with change indicator | |
| if change > 0: | |
| st.markdown(f"**{metric.capitalize()}:** {value:.4f} π **(+{change:.4f}, {change_pct:.2f}%)**") | |
| elif change < 0: | |
| st.markdown(f"**{metric.capitalize()}:** {value:.4f} π **({change:.4f}, {change_pct:.2f}%)**") | |
| else: | |
| st.markdown(f"**{metric.capitalize()}:** {value:.4f} (no change)") | |
| # Show visual diff of model config | |
| st.subheader("Configuration Changes") | |
| # Sample configs (in a real app, you'd fetch these from the API) | |
| base_config = { | |
| "hidden_size": 768, | |
| "num_attention_heads": 12, | |
| "num_hidden_layers": 6, | |
| "vocab_size": 30000 | |
| } | |
| compare_config = { | |
| "hidden_size": 1024, | |
| "num_attention_heads": 16, | |
| "num_hidden_layers": 8, | |
| "vocab_size": 30000 | |
| } | |
| # Generate a formatted diff | |
| base_str = json.dumps(base_config, indent=2).splitlines() | |
| compare_str = json.dumps(compare_config, indent=2).splitlines() | |
| diff = difflib.unified_diff( | |
| base_str, | |
| compare_str, | |
| fromfile=f'config_{base_version}', | |
| tofile=f'config_{compare_version}', | |
| lineterm='' | |
| ) | |
| diff_html = [] | |
| for line in diff: | |
| if line.startswith('+'): | |
| diff_html.append(f'<span style="color: green">{line}</span>') | |
| elif line.startswith('-'): | |
| diff_html.append(f'<span style="color: red">{line}</span>') | |
| elif line.startswith('@@'): | |
| diff_html.append(f'<span style="color: purple">{line}</span>') | |
| else: | |
| diff_html.append(line) | |
| st.markdown('<div style="background-color: #f5f5f5; padding: 10px; border-radius: 5px; font-family: monospace; white-space: pre-wrap;">' + '<br>'.join(diff_html) + '</div>', unsafe_allow_html=True) | |
| # Rollback functionality | |
| st.subheader("Rollback to Previous Version") | |
| rollback_version = st.selectbox( | |
| "Select version to rollback to", | |
| options=df["version"].tolist(), | |
| index=len(df)-2 # Default to second-to-last version | |
| ) | |
| if st.button("Rollback", use_container_width=True, type="primary"): | |
| with st.spinner("Rolling back to version " + rollback_version): | |
| # In a real implementation, this would call the HF API to perform the rollback | |
| st.success(f"Successfully rolled back to {rollback_version}") | |
| # Here you would update the model information and refresh the view | |