Welcome back, experimenter! So far, we’ve learned how to set up Trackio, log various metrics, manage experiments, and even sync with Hugging Face Spaces. You’re becoming a Trackio wizard!
In this chapter, we’re going to dive into making Trackio truly yours. While Trackio is designed to be lightweight and focused, its foundation on Gradio and Hugging Face Datasets provides powerful avenues for customization and extensibility. We’ll explore how to change the look and feel of your experiment dashboard and discuss how you can extend Trackio’s capabilities to fit unique tracking needs.
Why does this matter? Because every machine learning project is a snowflake! You might have specific branding requirements, a preference for dark mode, or unique metrics that aren’t perfectly captured by standard logging. Understanding customization and extensibility empowers you to adapt Trackio, ensuring it remains an invaluable tool as your projects evolve.
Before we begin, make sure you’re comfortable with launching the Trackio dashboard and logging basic metrics, as covered in previous chapters. Let’s make Trackio work even harder for you!
Understanding Trackio’s Architecture for Customization
Trackio’s design philosophy prioritizes simplicity and a local-first approach. It uses two key components that make customization straightforward:
- Gradio for the Dashboard: The interactive dashboard you use to visualize your experiments is a Gradio application. This is fantastic news because Gradio itself is highly customizable, especially regarding its visual themes.
- Hugging Face Datasets for Data Storage: All your logged metrics, parameters, and artifacts are stored in a structured way using Hugging Face Datasets. This open and accessible data format means you’re never locked in; you can always access your raw experiment data and build custom tools on top of it.
This architecture gives us two primary pathways for customization:
- Visual Customization: Changing the appearance of the existing Trackio dashboard through Gradio themes.
- Functional Extensibility: Building custom logic or visualizations that leverage Trackio’s stored data, or integrating specific data types not natively handled by Trackio.
Let’s visualize this relationship:
In this diagram, you can see how Trackio acts as a bridge, storing your data and presenting it via Gradio. Our customization efforts will focus on influencing the “Gradio Dashboard” through “Gradio Themes” and building “Custom Scripts/Tools” that interact with “Hugging Face Datasets.”
Customizing the Dashboard with Gradio Themes
Gradio, the framework powering the Trackio dashboard, comes with a rich set of built-in themes and allows for custom theme creation. This means you can easily switch your Trackio dashboard from its default look to something that better suits your aesthetic preferences or working environment (like a sleek dark mode!).
As of late 2025, Gradio (typically v4.x and later) offers several excellent themes directly accessible.
Step-by-Step: Applying a Gradio Theme
Let’s change the theme of our Trackio dashboard. This is incredibly straightforward!
Identify a Theme: Gradio offers themes like
soft,huggingface,monochrome,base,default, and more. You can import them directly fromgradio.themes. For this example, let’s try thesofttheme.Modify Your
trackio.run()Call: When you initialize and run Trackio, you can pass athemeargument to therun()function.First, open your
train_script.py(or whatever script you use to run your experiments).# train_script.py import trackio import time import random import gradio as gr # We'll need this to access themes # Initialize Trackio (this will create a new run or resume if specified) # Let's add a project name for better organization run = trackio.init(project="CustomTrackioExperiments") # Access a Gradio theme # Using gr.themes.Soft() for a gentle, modern look # You can also try gr.themes.Monochrome() or gr.themes.HuggingFace() my_custom_theme = gr.themes.Soft() print(f"Starting experiment: {run.id}") # Simulate a training loop for epoch in range(5): loss = 1.0 / (epoch + 1) + random.uniform(-0.1, 0.1) accuracy = 0.7 + (epoch * 0.05) + random.uniform(-0.02, 0.02) # Log metrics run.log({"epoch": epoch, "loss": loss, "accuracy": accuracy}) print(f"Epoch {epoch}: Loss={loss:.4f}, Accuracy={accuracy:.4f}") time.sleep(1) # Simulate training time # Simulate saving a model artifact # For demonstration, let's just create a dummy file with open("model_checkpoint.txt", "w") as f: f.write(f"Model trained for {epoch + 1} epochs. Final accuracy: {accuracy:.4f}") # Log the artifact run.log_artifact("model_checkpoint.txt", name="final-model", type="model") print(f"Experiment {run.id} finished.") # Now, launch the dashboard with our custom theme # The dashboard will open in your browser # Trackio will automatically pick up the latest run for the dashboard if not specified trackio.run(theme=my_custom_theme)Run Your Script: Execute your modified script from your terminal:
python train_script.pyTrackio will launch the dashboard, and you should immediately notice the
softtheme applied! The colors, fonts, and overall aesthetics will have changed.Feel free to experiment with other themes like
gr.themes.Monochrome()orgr.themes.HuggingFace()to see how they look.
Customizing Theme Colors (Advanced)
If the built-in themes aren’t enough, Gradio allows you to create highly customized themes by modifying individual CSS properties. While Trackio’s trackio.run() function directly accepts a gradio.themes.Base object, for deep customization, you’d typically create a new theme instance and modify its attributes.
Here’s a conceptual example of how you might define a custom dark theme:
# ... (previous imports and run.init() call) ...
# Define a custom dark theme
custom_dark_theme = gr.themes.Base(
primary_hue="purple", # Adjust primary color hue
secondary_hue="gray", # Adjust secondary color hue
neutral_hue="slate", # Adjust neutral color hue
font=(gr.themes.GoogleFont("Inter"), "ui-sans-serif", "sans-serif"),
font_mono=(gr.themes.GoogleFont("Fira Code"), "monospace"),
).set(
# Set specific color properties for dark mode
background_fill_dark="*primary_900",
block_background_fill_dark="*neutral_800",
container_background_fill_dark="*neutral_900",
text_color_dark="*neutral_50",
# ... many more properties can be customized
)
# ... (training loop and run.log() calls) ...
# Launch the dashboard with your custom theme
trackio.run(theme=custom_dark_theme)
Explanation:
- We import
gr.themes.Baseand other theme components fromgradio. - We create an instance of
gr.themes.Baseand pass arguments likeprimary_hue,secondary_hue, andneutral_hueto define the base color palette. - The
.set()method allows for granular control over specific CSS variables. Here, we’re adjustingbackground_fill_dark,block_background_fill_dark, etc., using Gradio’s internal color variable system (e.g.,*primary_900refers to a dark shade of the primary hue). - Important: This is a powerful feature of Gradio itself. For a complete list of customizable properties, always refer to the official Gradio theming documentation.
Trackio’s Extensibility: Beyond the Dashboard
While visual customization is great, true extensibility allows you to mold Trackio to handle unique data, integrate with other systems, or generate custom reports. Since Trackio is lightweight and stores data in an open format (Hugging Face Datasets), this is very achievable.
Trackio doesn’t have a complex plugin system or a vast array of formal “hooks” like some larger experiment trackers. Its extensibility comes from its Pythonic nature and the accessibility of its underlying data.
Pathway 1: Accessing Raw Data for Custom Analysis
The most direct way to extend Trackio is to read the data it logs and process it with your own Python scripts. Remember, Trackio stores your experiment data in a local (or remote) directory, often as a Hugging Face Dataset.
Let’s assume you have a trackio_runs directory created by Trackio.
# custom_analyzer.py
from datasets import load_from_disk
import pandas as pd
import os
# Define the path to your Trackio runs directory
# This assumes your trackio_runs directory is in the current working directory
TRACKIO_DIR = "trackio_runs"
def analyze_trackio_data(project_name):
project_path = os.path.join(TRACKIO_DIR, project_name)
if not os.path.exists(project_path):
print(f"Error: Project directory '{project_path}' not found.")
return
print(f"Analyzing data for project: {project_name}")
all_runs_data = []
# Iterate through each run in the project directory
for run_id in os.listdir(project_path):
run_path = os.path.join(project_path, run_id)
if os.path.isdir(run_path):
print(f" Loading data for run: {run_id}")
try:
# Logged metrics are typically stored in a 'logs' subdirectory
# Check the actual structure Trackio creates (e.g., run_id/logs/metrics)
# For simplicity, we assume a 'metrics' dataset directly under run_id
# In actual Trackio, it might be nested, e.g., run_id/metrics/dataset_name
# IMPORTANT: The actual path might vary slightly based on Trackio's internal structure.
# You might need to inspect your `trackio_runs` directory.
# A common structure is `trackio_runs/PROJECT_NAME/RUN_ID/logs_dataset`
metrics_path = os.path.join(run_path, "logs_dataset")
if os.path.exists(metrics_path):
dataset = load_from_disk(metrics_path)
df = dataset.to_pandas()
df['run_id'] = run_id # Add run ID for identification
all_runs_data.append(df)
print(f" Loaded {len(df)} entries.")
else:
print(f" No 'logs_dataset' found for run {run_id}. Skipping.")
except Exception as e:
print(f" Could not load data for run {run_id}: {e}")
if all_runs_data:
combined_df = pd.concat(all_runs_data, ignore_index=True)
print("\nCombined Data Head:")
print(combined_df.head())
# Example: Find the best run by accuracy
if 'accuracy' in combined_df.columns:
best_run = combined_df.loc[combined_df['accuracy'].idxmax()]
print(f"\nBest run by accuracy: {best_run['run_id']} with accuracy {best_run['accuracy']:.4f}")
return combined_df
else:
print("No data found for analysis.")
return None
if __name__ == "__main__":
# Make sure you've run an experiment with `project="CustomTrackioExperiments"`
# e.g., using the `train_script.py` from above.
project_df = analyze_trackio_data("CustomTrackioExperiments")
if project_df is not None:
print("\nPerforming further analysis...")
# You can now use pandas, matplotlib, seaborn, etc., for advanced visualizations
# For example, plot loss over epochs for all runs
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 6))
for run_id in project_df['run_id'].unique():
run_df = project_df[project_df['run_id'] == run_id]
plt.plot(run_df['epoch'], run_df['loss'], label=f"Run {run_id[:8]} - Loss")
plt.xlabel("Epoch")
plt.ylabel("Loss")
plt.title("Loss over Epochs for All Runs")
plt.legend()
plt.grid(True)
plt.show()
Explanation:
- We import
load_from_diskfrom thedatasetslibrary, which Trackio uses internally. - The
analyze_trackio_datafunction iterates through yourtrackio_runsdirectory, loads thelogs_datasetfor each run, and converts it to a Pandas DataFrame. - Crucially: The exact path to the metrics dataset (
logs_dataset) might vary slightly depending on Trackio’s internal updates. You might need to manually inspect yourtrackio_runs/PROJECT_NAME/RUN_ID/directory structure to find the correctload_from_diskpath. - Once you have your data in a DataFrame, the possibilities are endless! You can perform custom aggregations, statistical analysis, or create bespoke visualizations using libraries like
matplotliborseaborn.
Pathway 2: Extending the Gradio Dashboard (Conceptual)
Since the Trackio dashboard is a Gradio app, you could theoretically build your own Gradio app that integrates with Trackio’s data or even extends its functionality. This is more advanced and would involve creating a separate Gradio application that reads Trackio’s data.
Here’s a conceptual idea:
# custom_dashboard_extension.py
import gradio as gr
from datasets import load_from_disk
import pandas as pd
import os
# This is a simplified example. In a real scenario, you'd want to
# abstract data loading and potentially integrate with Trackio's
# internal run management if you wanted to select specific runs.
def load_latest_run_data(project_name="CustomTrackioExperiments"):
"""Loads data for the latest run in a given project."""
trackio_dir = "trackio_runs"
project_path = os.path.join(trackio_dir, project_name)
if not os.path.exists(project_path):
return pd.DataFrame() # Return empty if no project
run_dirs = [d for d in os.listdir(project_path) if os.path.isdir(os.path.join(project_path, d))]
if not run_dirs:
return pd.DataFrame()
# Sort by modification time to get the latest run
run_dirs.sort(key=lambda x: os.path.getmtime(os.path.join(project_path, x)), reverse=True)
latest_run_id = run_dirs[0]
run_path = os.path.join(project_path, latest_run_id)
metrics_path = os.path.join(run_path, "logs_dataset")
if os.path.exists(metrics_path):
dataset = load_from_disk(metrics_path)
df = dataset.to_pandas()
df['run_id'] = latest_run_id
return df
return pd.DataFrame()
def plot_metrics(metric_name):
df = load_latest_run_data()
if df.empty or metric_name not in df.columns or 'epoch' not in df.columns:
return "No data or metric found to plot."
# Use a simple plot (e.g., HTML image for Gradio)
import matplotlib.pyplot as plt
plt.figure(figsize=(8, 4))
plt.plot(df['epoch'], df[metric_name])
plt.xlabel("Epoch")
plt.ylabel(metric_name)
plt.title(f"Latest Run: {metric_name} over Epochs")
plt.grid(True)
# Save plot to a temporary buffer and return as Gradio Image
from io import BytesIO
import base64
buf = BytesIO()
plt.savefig(buf, format='png')
plt.close()
img_str = "data:image/png;base64," + base64.b64encode(buf.getvalue()).decode()
return img_str
# Define the Gradio interface
with gr.Blocks(theme=gr.themes.Soft()) as demo:
gr.Markdown("# Custom Trackio Data Viewer")
gr.Markdown("This is a separate Gradio app showing custom visualizations from Trackio data.")
metric_dropdown = gr.Dropdown(
["loss", "accuracy"], # Assuming these metrics are logged
label="Select Metric to Plot"
)
plot_output = gr.Image(label="Metric Plot")
metric_dropdown.change(plot_metrics, inputs=metric_dropdown, outputs=plot_output)
# Launch this custom Gradio app
if __name__ == "__main__":
demo.launch()
Explanation:
- This script creates a separate Gradio application. It doesn’t modify Trackio’s built-in dashboard but acts as an additional, specialized viewer.
- It includes a
load_latest_run_datafunction that mimics how Trackio’s dashboard would access data, focusing on the most recent run. - The
plot_metricsfunction generates amatplotlibplot and returns it as a base64 encoded image string, which Gradio can display. - A
gr.Blocksinterface is used to create a simple dashboard with a dropdown to select a metric and an image output for the plot. - You would run this
custom_dashboard_extension.pyscript independently to view your custom dashboard.
This demonstrates how Trackio’s open architecture allows you to build sophisticated tools around it, rather than being limited to its core features.
Mini-Challenge: Custom Theme and Data Observation
Let’s put your new knowledge to the test!
Challenge:
- Modify your
train_script.pyto use thegr.themes.Monochrome()theme for the Trackio dashboard. - In the same
train_script.py, log a completely new, custom metric that Trackio wouldn’t natively expect, such ascpu_temp_celsius(simulated, of course!). Log a random value for it in each epoch. - Run the
custom_analyzer.pyscript (from Pathway 1) to verify that your newcpu_temp_celsiusmetric is present in the combined DataFrame and perform a simple analysis (e.g., print the averagecpu_temp_celsiusacross all logged epochs).
Hint:
- For the theme, remember to import
gradio as grand then usegr.themes.Monochrome(). - For the custom metric, simply add it to the dictionary you pass to
run.log(). Trackio is flexible and will log whatever key-value pairs you provide. - For
custom_analyzer.py, you’ll need to ensure theprojectname matches and then look for your new column in the DataFrame.
What to Observe/Learn:
- How easily you can change the visual identity of your dashboard.
- Trackio’s flexibility in logging arbitrary data.
- The power of directly accessing Trackio’s underlying data store for custom analysis, bypassing the default dashboard’s limitations.
Common Pitfalls & Troubleshooting
Theme Not Applying:
- Issue: You’ve added
theme=my_custom_themebut the dashboard still looks default. - Solution:
- Ensure you have
import gradio as grat the top of your script. - Verify that
my_custom_themeis indeed agradio.themes.Baseobject (or one of its subclasses likegr.themes.Soft()). - Make sure you are passing the
themeargument totrackio.run()(ortrackio.init()if you’re usinginitto launch the dashboard in a non-blocking way), and not an earlier function call. - Clear your browser cache, as sometimes old CSS might be stubbornly cached.
- Ensure you have
- Issue: You’ve added
Custom Data Not Appearing in Dashboard:
- Issue: You logged
cpu_temp_celsius, but you don’t see it as a separate plot or table column in the Trackio dashboard. - Solution: Trackio’s default dashboard, while versatile, has pre-defined panels for common metrics like
lossandaccuracy. If you log a truly custom metric, it might appear in a generic “Table” view or “Raw Data” tab, but not necessarily get its own dedicated plot automatically. This is expected behavior for a lightweight tracker. If you need a custom visualization for it, that’s where the “Pathway 2: Extending the Gradio Dashboard (Conceptual)” approach comes in, where you’d build a specific Gradio component to plot that metric from the raw data.
- Issue: You logged
datasets.load_from_diskPath Issues:- Issue: Your
custom_analyzer.pyscript fails with aFileNotFoundErroror cannot load the dataset. - Solution:
- The path
os.path.join(run_path, "logs_dataset")is a common convention, but Trackio’s internal structure might evolve. - Best practice: Manually navigate to your
trackio_runs/PROJECT_NAME/RUN_ID/directory after running an experiment. Look for a subdirectory that contains files likedataset_info.json,data-00000-of-00001.arrow, etc. This is your actual dataset directory. Adjust themetrics_pathincustom_analyzer.pyaccordingly. For example, it might beos.path.join(run_path, "metrics_data")or similar.
- The path
- Issue: Your
Summary
Congratulations! You’ve successfully explored how to customize and extend Trackio to better suit your machine learning workflow.
Here’s a quick recap of what we covered:
- Trackio’s Architecture: Understood that Trackio leverages Gradio for its dashboard and Hugging Face Datasets for data storage, enabling flexible customization.
- Gradio Dashboard Theming: Learned how to apply built-in Gradio themes (like
gr.themes.Soft()orgr.themes.Monochrome()) to change the visual appearance of your Trackio dashboard. - Custom Theme Creation (Conceptual): Briefly touched upon how to create more granular custom themes using
gr.themes.Base().set(). - Accessing Raw Data: Discovered how to directly load Trackio’s logged data using
datasets.load_from_diskfor custom analysis and visualization outside the default dashboard. - Extending the Dashboard (Conceptual): Explored the idea of building separate, custom Gradio applications that consume Trackio’s data for specialized views.
You now have the tools to make your Trackio experience both visually appealing and functionally robust, ensuring it adapts to the unique demands of your ML projects.
What’s Next?
In our final chapter, we’ll bring everything together by exploring real-world machine learning experiment tracking scenarios, discussing best practices, and looking at how Trackio fits into a complete MLOps workflow. Get ready to solidify your expertise!
References
- Hugging Face Trackio Official Documentation: https://huggingface.co/docs/trackio/en/index
- Gradio Official Documentation: https://www.gradio.app/docs/
- Gradio Theming Guide: https://www.gradio.app/docs/theme
- Hugging Face Datasets Library: https://huggingface.co/docs/datasets/index
This page is AI-assisted and reviewed. It references official documentation and recognized resources where relevant.