tune-duel / README.md
gokceuludogan's picture
initial commit
7f8c6a3

A newer version of the Gradio SDK is available: 6.1.0

Upgrade
metadata
title: Tune Duel
emoji: 📊
colorFrom: purple
colorTo: green
sdk: gradio
sdk_version: 5.49.1
app_file: app.py
pinned: false

Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference

🎶 Tune Duel - Recommender System Competition

A Gradio-based web application for comparing music recommendation models through head-to-head battles using an Elo rating system.

Overview

Tune Duel is a competitive platform where different music recommendation models compete against each other. Users input their favorite songs with ratings (1-5 stars), and the system automatically matches them with Spotify IDs for enhanced recommendation capabilities. The system presents recommendations from two different models side-by-side with embedded Spotify players, allowing users to listen and compare tracks directly in the interface. Users then vote on which model provided better recommendations, and the results are used to update Elo ratings for each model.

Features

  • Song Rating System: Users can rate multiple songs (1-5 stars) to provide richer context for recommendations
  • Automatic Spotify ID Matching: System automatically finds and includes Spotify IDs for input songs
  • Real-time Track Suggestions: As users type song names, the system shows matching tracks from the database
  • Random Track Selection: Users can click random buttons to quickly populate fields with valid tracks from the database
  • Spotify Web Player Integration: Embedded Spotify players for both input songs and recommendations
  • Track Validation: Built-in validation ensures users enter songs that exist in the tracks database
  • Enhanced Recommendation Display: Recommendations include embedded Spotify players for immediate preview
  • Head-to-Head Model Comparison: Compare recommendations from two different models simultaneously
  • Elo Rating System: Models are ranked using the Elo rating system (similar to chess ratings)
  • Real-time Leaderboard: Live leaderboard showing current model rankings
  • Flexible Model Integration: Support for both HTTP API and Python-based models
  • Caching System: Intelligent caching to improve performance and reduce API calls
  • Vote Logging: Complete audit trail of all votes and interactions
  • Modern Web Interface: Clean, responsive Gradio-based UI

Project Structure

gradio/
├── app.py                 # Main Gradio application
├── models.yaml           # Model configuration file
├── tracks.csv            # Track database with Spotify IDs
├── requirements.txt      # Python dependencies
├── README.md            # This file
├── state/               # Persistent data storage
│   ├── elo.pkl         # Elo ratings (pickle)
│   ├── leaderboard.csv # Leaderboard data
│   └── votes.jsonl     # Vote history log
├── team_alpha/          # Example team implementation
│   └── src/
│       └── recommender.py
├── team_beta/           # Example team implementation
│   └── src/
│       └── recommender.py
└── team_gamma/          # Example team implementation
    └── src/
        └── recommender.py

Installation

  1. Clone the repository:

    git clone <repository-url>
    cd gradio
    
  2. Install dependencies:

    pip install -r requirements.txt
    
  3. Configure models (see Configuration section below)

  4. Run the application:

    python app.py
    
  5. Access the web interface: Open your browser and navigate to http://localhost:7860

Configuration

Model Configuration (models.yaml)

Models are configured in the models.yaml file. Each model can be either:

HTTP API Models

models:
  - name: "my_api_model"
    type: http
    endpoint: "https://api.example.com/recommend"
    timeout: 8
    topk: 10

API Requirements:

  • Endpoint must accept POST requests
  • Request body: {"song_ratings": [{"song": "song name", "rating": 5, "spotify_id": "abc123"}, ...]}
  • Response format: {"items": ["item1", "item2", ...]} or {"recommendations": [...]}

Python Models

models:
  - name: "my_python_model"
    type: python
    callable: "team_alpha.src.recommender.query"
    topk: 10

Python Requirements:

  • Must be importable as a module
  • Function signature: query(song_ratings: List[Dict[str, any]]) -> List[Tuple[str, str]]
  • Should return a list of (spotify_id, track_name) tuples

Example Model Implementation

# team_alpha/src/recommender.py
def query(song_ratings: List[Dict[str, any]]) -> List[Tuple[str, str]]:
    """
    Generate music recommendations based on user's song ratings.
    
    Args:
        song_ratings: List of dicts with 'song', 'rating', and 'spotify_id' keys
                     e.g., [{"song": "Taylor Swift - 22", "rating": 5, "spotify_id": "abc123"}, ...]
        
    Returns:
        List of (spotify_id, track_name) tuples
    """
    # Your recommendation logic here
    recommendations = [
        ("4iV5W9uYEdYUVa79Axb7Rh", "Never Gonna Give You Up"),
        ("0VjIjW4GlUZAMYd2vXMi3b", "Blinding Lights"),
        # ... more recommendations
    ]
    return recommendations

Usage

Basic Workflow

  1. Enter Songs with Ratings: Input up to 5 songs with ratings (1-5 stars) in the provided fields. Use the "Add More Songs" button to reveal additional input fields for songs 4-5. As you type, matching tracks from the database will appear as suggestions. You can also click the 🎲 Random buttons to quickly fill fields with random tracks, or use "🎲 Fill All Random" to populate all fields at once.
  2. Preview Input Songs: Click the ▶️ Play button next to any song to start the embedded Spotify player and listen to the track
  3. Select Models: Choose two different models to compare (or use "Random Pair")
  4. Get Recommendations: Click "Recommend" to fetch suggestions from both models
  5. Compare Results: Review the recommendations side-by-side with embedded Spotify players for each recommended track
  6. Listen and Vote: Listen to recommended tracks using the embedded players, then choose which model provided better recommendations:
    • A Wins: Model A had better recommendations
    • B Wins: Model B had better recommendations
    • Tie: Both models performed equally well
    • Skip: Skip this comparison

Elo Rating System

  • Starting Rating: 1200 (all models start equal)
  • K-Factor: 16 (rating change sensitivity)
  • Outcomes:
    • Win: +16 points (expected)
    • Loss: -16 points (expected)
    • Tie: 0 points (expected)

Enhanced Data Format

The system now provides recommenders with rich data including Spotify IDs:

Input Song Ratings Format:

song_ratings = [
    {
        "song": "Blinding Lights by The Weeknd",
        "rating": 5,
        "spotify_id": "0VjIjW4GlUZAMYd2vXMi3b"
    },
    {
        "song": "Shape of You by Ed Sheeran",
        "rating": 4,
        "spotify_id": "4uLU6hMCjMI75M1A2tKUQC"
    }
]

Recommendation Output Format:

recommendations = [
    ("4iV5W9uYEdYUVa79Axb7Rh", "Never Gonna Give You Up"),
    ("0VjIjW4GlUZAMYd2vXMi3b", "Blinding Lights"),
    ("4uLU6hMCjMI75M1A2tKUQC", "Shape of You")
]

Benefits for Recommenders:

  • Song names: Human-readable context
  • Ratings: User preference strength (1-5 stars)
  • Spotify IDs: Access to audio features, metadata, popularity, genre, etc.

Leaderboard

The leaderboard shows:

  • Model Name: Name of the recommendation model
  • Elo Rating: Current Elo rating (higher = better)

Spotify Integration

Track Database

The system includes a comprehensive track database (tracks.csv) with:

  • Track names and artist names
  • Spotify track IDs for each track
  • Automatic matching of user input to Spotify IDs

Spotify Web Players

  • Input song preview: Click ▶️ buttons to preview input songs
  • Recommendation preview: Each recommended track includes an embedded Spotify player
  • Real-time playback: Listen to tracks without leaving the interface

Model Interface

All models must implement the following interface:

def query(song_ratings: List[Dict[str, any]], topk: int = 5) -> List[Tuple[str, str]]:
    """
    Generate recommendations for given song ratings with Spotify integration.
    
    Args:
        song_ratings: List of dicts with 'song', 'rating', and 'spotify_id' keys
                     e.g., [
                         {"song": "Blinding Lights by The Weeknd", "rating": 5, "spotify_id": "0VjIjW4GlUZAMYd2vXMi3b"},
                         {"song": "Shape of You by Ed Sheeran", "rating": 4, "spotify_id": "4uLU6hMCjMI75M1A2tKUQC"}
                     ]
        topk: Maximum number of recommendations to return (default: 5)
        
    Returns:
        List of (spotify_id, track_name) tuples
        e.g., [
            ("4iV5W9uYEdYUVa79Axb7Rh", "Never Gonna Give You Up"),
            ("0VjIjW4GlUZAMYd2vXMi3b", "Blinding Lights")
        ]
    """
    pass

Input Data Structure:

  • song: Human-readable track name (e.g., "Blinding Lights by The Weeknd")
  • rating: User preference rating (1-5 stars)
  • spotify_id: Spotify track ID for enhanced capabilities (e.g., "0VjIjW4GlUZAMYd2vXMi3b")

Output Data Structure:

  • spotify_id: Spotify track ID for the recommended track
  • track_name: Human-readable track name for display

Configuration Parameters

  • name: Unique identifier for the model
  • type: Either "http" or "python"
  • endpoint: HTTP URL (for http models) - must accept enhanced song_ratings format
  • callable: Python module path (for python models) - must implement enhanced interface
  • timeout: Request timeout in seconds (default: 3) - optimized for user experience
  • topk: Number of recommendations to return (default: 10)

Timeout Configuration:

  • Default: 8 seconds for both HTTP and Python models
  • Purpose: Ensures recommendations return quickly for better user experience
  • Override: Can be customized per model in models.yaml
  • Python Models: Uses signal-based timeout handling
  • HTTP Models: Uses requests library timeout

State Management

The application maintains several state files:

  • state/elo.pkl: Current Elo ratings for all models
  • state/leaderboard.csv: Human-readable leaderboard
  • state/votes.jsonl: Complete vote history
  • state/cache.pkl: Recommendation cache for performance

Logging

All votes are logged with:

  • Timestamp
  • Client IP address
  • Song name
  • Model A and B names
  • Vote outcome

Troubleshooting

Common Issues

  1. "No models configured": Check that models.yaml exists and contains valid model definitions
  2. "Failed to get recommendations": Verify model endpoints are accessible or Python modules are importable
  3. "Duplicate model names": Ensure all model names in models.yaml are unique
  4. Import errors: Check that Python model paths are correct and modules are accessible
  5. Spotify Player Issues:
    • "No preview available": Ensure tracks exist in tracks.csv with valid Spotify IDs
    • Players not loading: Check internet connection and Spotify embed permissions
  6. Track Validation Errors:
    • "Track not found": Use exact track names from database or click 🎲 Random buttons
    • Format issues: Enter tracks as "Song Name by Artist Name"
  7. Model Format Issues:
    • Wrong return format: Ensure models return List[Tuple[str, str]] format
    • Missing Spotify IDs: Check that input song ratings include spotify_id field
  8. Timeout Issues:
    • Model timeout: Models must return results within 3 seconds
    • Slow recommendations: Optimize model code or increase timeout in models.yaml
    • Python model timeout: Use efficient algorithms and avoid blocking operations
    • HTTP model timeout: Ensure endpoints respond quickly or increase timeout

Debug Mode

For debugging, you can modify the application to run in debug mode:

# In app.py, change the launch call:
demo.queue(default_concurrency_limit=20).launch(
    server_name="0.0.0.0", 
    server_port=7860,
    debug=True
)

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Implement your changes
  4. Add tests if applicable
  5. Submit a pull request

License

MIT LICENSE Copyright (c) 2025 bouncmpe343

Acknowledgments

  • Built with Gradio
  • Uses Elo rating system for fair model comparison
  • Inspired by competitive machine learning platforms