Files
Claude 1456995462 Add complete Mail Fine-Tuning Web-App for macOS Apple Silicon
Implemented a full-stack web application for fine-tuning LLMs on email data, optimized for Apple Silicon (M4 Pro with 24GB RAM).

Features:
- Mail import with drag & drop support (.mbox, .eml, .txt)
- Automated mail cleaning and preprocessing
- Interactive labeling interface with keyboard shortcuts
- Training data export to JSONL format
- MLX-based LoRA fine-tuning with live updates
- Model evaluation and comparison interface
- Server-Sent Events for real-time training progress
- Dark theme UI optimized for extended use

Technical Stack:
- Backend: FastAPI with SQLite database
- Frontend: Vanilla HTML/CSS/JavaScript (no external dependencies)
- ML Framework: MLX for Apple Silicon optimization
- Models: Support for Mistral 7B and Llama 3 8B via MLX

Components:
- data_manager.py: SQLite operations for mail storage and labeling
- mail_parser.py: Parser for multiple mail formats with cleaning
- training.py: MLX training wrapper with LoRA support
- inference.py: Model loading and inference for evaluation
- main.py: FastAPI backend with REST API and SSE
- Frontend: Complete UI with all features

Documentation:
- Comprehensive README with installation and usage guide
- Quick-start guide for rapid setup
- Example mails for testing
- Troubleshooting and best practices

Ready for local deployment and fine-tuning workflows.
2025-12-03 07:35:35 +00:00

255 lines
11 KiB
HTML

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mail Fine-Tuning App</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="app-container">
<!-- Sidebar Navigation -->
<nav class="sidebar">
<h1>Mail Fine-Tuning</h1>
<ul class="nav-menu">
<li><a href="#" data-view="import" class="nav-link active">📥 Mail Import</a></li>
<li><a href="#" data-view="labeling" class="nav-link">🏷️ Labeling</a></li>
<li><a href="#" data-view="export" class="nav-link">📊 Export & Stats</a></li>
<li><a href="#" data-view="models" class="nav-link">🤖 Modelle</a></li>
<li><a href="#" data-view="training" class="nav-link">🎯 Training</a></li>
<li><a href="#" data-view="evaluation" class="nav-link">🧪 Evaluation</a></li>
</ul>
</nav>
<!-- Main Content -->
<main class="main-content">
<!-- Import View -->
<div id="import-view" class="view active">
<h2>Mail Import</h2>
<div class="upload-section">
<div class="dropzone" id="dropzone">
<p>📂 Dateien hier ablegen oder klicken</p>
<p class="hint">Unterstützt: .eml, .mbox, .txt</p>
<input type="file" id="file-input" multiple accept=".eml,.mbox,.txt" hidden>
</div>
</div>
<div class="mail-list-section">
<div class="section-header">
<h3>Importierte Mails (<span id="mail-count">0</span>)</h3>
<button id="refresh-mails" class="btn btn-secondary">🔄 Aktualisieren</button>
</div>
<div id="mail-list" class="mail-list">
<!-- Mails werden hier eingefügt -->
</div>
</div>
</div>
<!-- Labeling View -->
<div id="labeling-view" class="view">
<div class="section-header">
<h2>Mail Labeling</h2>
<div class="filter-controls">
<select id="status-filter">
<option value="">Alle anzeigen</option>
<option value="unlabeled" selected>Nur Unlabeled</option>
<option value="labeled">Nur Labeled</option>
<option value="skip">Übersprungen</option>
</select>
</div>
</div>
<div class="progress-bar">
<div class="progress-fill" id="labeling-progress"></div>
<span class="progress-text" id="progress-text">0 / 0 gelabelt</span>
</div>
<div class="keyboard-hints">
Shortcuts: <kbd>N</kbd> Nächste | <kbd>S</kbd> Speichern | <kbd>K</kbd> Skip
</div>
<div id="labeling-container">
<!-- Labeling Interface wird hier geladen -->
</div>
</div>
<!-- Export View -->
<div id="export-view" class="view">
<h2>Daten Export & Statistiken</h2>
<div class="stats-grid" id="stats-grid">
<!-- Stats werden hier eingefügt -->
</div>
<div class="export-section">
<h3>Training-Daten exportieren</h3>
<div class="export-controls">
<label>
Train/Val Split:
<input type="number" id="train-split" value="90" min="50" max="95" step="5">%
</label>
<button id="export-jsonl" class="btn btn-primary">📦 JSONL generieren</button>
</div>
<div id="export-result"></div>
</div>
</div>
<!-- Models View -->
<div id="models-view" class="view">
<h2>Modell-Verwaltung</h2>
<div class="model-section">
<h3>Verfügbare Modelle</h3>
<div id="models-list" class="models-list">
<!-- Modelle werden hier geladen -->
</div>
<div class="model-download">
<h3>Modell herunterladen</h3>
<p class="info-text">
Modelle müssen manuell heruntergeladen werden. Empfohlen:
</p>
<ul>
<li>mlx-community/Mistral-7B-Instruct-v0.3-4bit</li>
<li>mlx-community/Meta-Llama-3-8B-Instruct-4bit</li>
</ul>
<p class="code-example">
huggingface-cli download [model-name] --local-dir models/[model-name]
</p>
</div>
</div>
</div>
<!-- Training View -->
<div id="training-view" class="view">
<h2>Training</h2>
<div class="training-config">
<h3>Konfiguration</h3>
<form id="training-form">
<div class="form-group">
<label>Modell:</label>
<select id="training-model" required>
<option value="">-- Modell wählen --</option>
</select>
</div>
<div class="form-group">
<label>
Learning Rate: <span id="lr-value">1e-5</span>
</label>
<input type="range" id="learning-rate"
min="-6" max="-4" step="0.1" value="-5">
</div>
<div class="form-group">
<label>
Epochs: <span id="epochs-value">3</span>
</label>
<input type="range" id="epochs"
min="1" max="10" value="3">
</div>
<div class="form-group">
<label>Batch Size:</label>
<select id="batch-size">
<option value="1">1</option>
<option value="2">2</option>
<option value="4" selected>4</option>
<option value="8">8</option>
</select>
</div>
<div class="form-group">
<label>LoRA Rank:</label>
<select id="lora-rank">
<option value="4">4</option>
<option value="8" selected>8</option>
<option value="16">16</option>
<option value="32">32</option>
</select>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary" id="start-training">
▶️ Training starten
</button>
<button type="button" class="btn btn-danger" id="stop-training" disabled>
⏹️ Training stoppen
</button>
</div>
</form>
</div>
<div class="training-status" id="training-status">
<!-- Training Status wird hier angezeigt -->
</div>
<div class="training-charts">
<div class="chart-container">
<h4>Training Loss</h4>
<canvas id="train-loss-chart"></canvas>
</div>
<div class="chart-container">
<h4>Validation Loss</h4>
<canvas id="val-loss-chart"></canvas>
</div>
</div>
</div>
<!-- Evaluation View -->
<div id="evaluation-view" class="view">
<h2>Modell Evaluation</h2>
<div class="eval-controls">
<h3>Chat Interface</h3>
<div class="form-group">
<label>Task Type:</label>
<select id="eval-task-type">
<option value="Zusammenfassen">Zusammenfassen</option>
<option value="Antwort schreiben">Antwort schreiben</option>
<option value="Kategorisieren">Kategorisieren</option>
<option value="Action Items">Action Items</option>
<option value="Custom">Custom</option>
</select>
</div>
<div class="form-group">
<label>Mail-Text:</label>
<textarea id="eval-mail-text" rows="6" placeholder="Mail-Text hier eingeben..."></textarea>
</div>
<div class="form-group">
<button id="load-test-prompt" class="btn btn-secondary">📝 Test-Beispiel laden</button>
<button id="run-comparison" class="btn btn-primary">🔍 Vergleich starten</button>
</div>
</div>
<div class="comparison-results">
<div class="result-box">
<h4>Base Model</h4>
<div id="base-result" class="result-content">
Noch kein Ergebnis
</div>
</div>
<div class="result-box">
<h4>Fine-tuned Model</h4>
<div id="finetuned-result" class="result-content">
Noch kein Ergebnis
</div>
</div>
</div>
</div>
</main>
</div>
<!-- Toast Notifications -->
<div id="toast-container"></div>
<script src="app.js"></script>
</body>
</html>