Zandy-Wandy commited on
Commit
cb3cf0b
·
verified ·
1 Parent(s): 4f0238f

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +440 -416
README.md CHANGED
@@ -1,416 +1,440 @@
1
- # Touch Grass 🎵
2
-
3
- **A Lightweight Music AI Assistant Fine-Tuned from Qwen3.5**
4
-
5
- Touch Grass is a specialized music AI assistant built by fine-tuning Qwen3.5 models (3B and 7B variants) with music-specific capabilities. It understands guitar, piano, drums, vocals, music theory, ear training, songwriting, and production—with emotional intelligence to help musicians through frustration.
6
-
7
- ## 🌟 Features
8
-
9
- - **Two Model Sizes**: TouchGrass-3B (CPU-friendly) and TouchGrass-7B (GPU-enhanced)
10
- - **Music Tokenizer Extension**: Adds 21+ music-specific tokens to Qwen3.5's vocabulary
11
- - **Five Specialized Modules**:
12
- - 🎸 **Tab & Chord Generation**: Creates and validates guitar tabs, chord diagrams
13
- - 🎹 **Music Theory Engine**: Scales, chords, intervals, progressions, circle of fifths
14
- - 👂 **Ear Training**: Interval identification with song references, solfege exercises
15
- - 😌 **EQ Adapter**: Frustration detection and emotional response adaptation
16
- - ✍️ **Song Writing Assistant**: Chord progressions, lyrics, hooks, production tips
17
- - **LoRA Fine-Tuning**: Efficient adaptation without full model retraining
18
- - **HuggingFace Compatible**: Production-ready with custom config and tokenizer classes
19
- - **Ollama Support**: Run locally with Ollama modelfiles
20
- - **Unified Inference**: Instrument context switching (guitar, piano, drums, vocals, theory, production)
21
- - **Synthetic Data Pipeline**: 10 categories, 80+ templates covering all music domains
22
-
23
- ## 🏗️ Architecture
24
-
25
- ```
26
- TouchGrass/
27
- ├── configs/ # Model configurations
28
- │ ├── touchgrass_3b_config.py # 3B variant config
29
- │ ├── touchgrass_7b_config.py # 7B variant config
30
- │ └── training_config.py # Training hyperparameters
31
- ├── tokenizer/
32
- │ └── music_token_extension.py # Extends Qwen tokenizer with music tokens
33
- ├── models/ # Specialized music modules
34
- │ ├── tab_chord_module.py # Guitar tabs and chords
35
- │ ├── music_theory_module.py # Theory knowledge
36
- │ ├── ear_training_module.py # Ear training exercises
37
- │ ├── eq_adapter.py # Emotional intelligence
38
- │ └── songwriting_module.py # Song creation assistance
39
- ├── data/
40
- │ ├── music_qa_generator.py # Synthetic dataset generator
41
- │ ├── chat_formatter.py # Qwen chat format converter
42
- │ └── dataset_loader.py # PyTorch dataset
43
- ├── training/
44
- │ ├── losses.py # Multi-task loss functions
45
- │ ├── trainer.py # LoRA-aware trainer
46
- │ └── train.py # Main training entry point
47
- ├── inference/
48
- │ └── inference.py # Unified inference with context
49
- ├── benchmarks/
50
- │ ├── evaluate_music_modules.py # Module-level benchmarks
51
- │ └── evaluate_inference.py # End-to-end inference benchmarks
52
- ├── tests/ # Comprehensive test suite
53
- │ ├── test_*.py # Unit tests for each module
54
- ── conftest.py # Pytest fixtures
55
- │ └── run_tests.py # Test runner
56
- ── configuration_touchgrass.py # HuggingFace config class
57
- ├── tokenization_touchgrass.py # HuggingFace tokenizer wrapper
58
- ├── ollama_3b_modelfile # Ollama config for 3B
59
- ├── ollama_7b_modelfile # Ollama config for 7B
60
- ── train.py # Main training script
61
- ```
62
-
63
- ## 📦 Installation
64
-
65
- ### Prerequisites
66
-
67
- - Python 3.10+
68
- - PyTorch 2.0+
69
- - Transformers (HuggingFace)
70
- - PEFT (LoRA)
71
- - Datasets
72
- - Pytest (for testing)
73
-
74
- ### Setup
75
-
76
- ```bash
77
- # Clone the repository
78
- cd TouchGrass
79
-
80
- # Install dependencies
81
- pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
82
- pip install transformers peft datasets accelerate tqdm pytest
83
-
84
- # Optional: For GPU support
85
- pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
86
- ```
87
-
88
- ## 🚀 Quick Start
89
-
90
- ### 1. Generate Training Data
91
-
92
- ```bash
93
- python -c "
94
- from TouchGrass.data.music_qa_generator import MusicQAGenerator
95
- from TouchGrass.data.chat_formatter import ChatFormatter
96
-
97
- # Generate synthetic dataset
98
- generator = MusicQAGenerator(seed=42)
99
- dataset = generator.generate_dataset(num_samples=1000, output_path='data/music_qa.jsonl')
100
-
101
- # Format for Qwen
102
- formatter = ChatFormatter()
103
- formatted = formatter.format_dataset(dataset)
104
- train_data, val_data = formatter.create_splits(formatted, val_size=0.1)
105
-
106
- formatter.save_dataset(train_data, 'data/train.jsonl')
107
- formatter.save_dataset(val_data, 'data/val.jsonl')
108
- "
109
- ```
110
-
111
- ### 2. Train the Model
112
-
113
- ```bash
114
- # Train 3B variant
115
- python train.py \
116
- --base_model Qwen/Qwen3.5-3B-Instruct \
117
- --train_data data/train.jsonl \
118
- --val_data data/val.jsonl \
119
- --output_dir checkpoints/touchgrass-3b \
120
- --lora_r 16 \
121
- --lora_alpha 32 \
122
- --batch_size 4 \
123
- --gradient_accumulation_steps 4 \
124
- --learning_rate 2e-4 \
125
- --num_epochs 3 \
126
- --mixed_precision fp16
127
-
128
- # Train 7B variant (requires GPU with 16GB+ VRAM)
129
- python train.py \
130
- --base_model Qwen/Qwen3.5-7B-Instruct \
131
- --train_data data/train.jsonl \
132
- --val_data data/val.jsonl \
133
- --output_dir checkpoints/touchgrass-7b \
134
- --lora_r 16 \
135
- --lora_alpha 32 \
136
- --batch_size 2 \
137
- --gradient_accumulation_steps 8 \
138
- --learning_rate 1e-4 \
139
- --num_epochs 3 \
140
- --mixed_precision bf16
141
- ```
142
-
143
- ### 3. Run Inference
144
-
145
- ```python
146
- from TouchGrass.inference.inference import TouchGrassInference
147
-
148
- # Load model
149
- model = TouchGrassInference(
150
- model_path="checkpoints/touchgrass-3b",
151
- device="cpu" # or "cuda"
152
- )
153
-
154
- # Single query with instrument context
155
- response = model.generate(
156
- prompt="How do I play a G major chord?",
157
- instrument="guitar",
158
- skill_level="beginner",
159
- max_new_tokens=200
160
- )
161
- print(response)
162
-
163
- # Interactive mode
164
- model.chat(instrument="piano")
165
- ```
166
-
167
- ### 4. Use with Ollama
168
-
169
- ```bash
170
- # Create modelfile from provided template
171
- cat ollama_3b_modelfile > Modelfile
172
-
173
- # Build and run
174
- ollama create touchgrass-3b -f Modelfile
175
- ollama run touchgrass-3b "How do I play a G major chord on guitar?"
176
- ```
177
-
178
- ### 5. Use with HuggingFace
179
-
180
- ```python
181
- from transformers import AutoModelForCausalLM, AutoTokenizer
182
-
183
- # Load with custom config and tokenizer
184
- config = TouchGrassConfig.from_pretrained("checkpoints/touchgrass-3b")
185
- tokenizer = TouchGrassTokenizer.from_pretrained("checkpoints/touchgrass-3b")
186
- model = AutoModelForCausalLM.from_pretrained(
187
- "checkpoints/touchgrass-3b",
188
- config=config,
189
- device_map="auto"
190
- )
191
-
192
- # Generate
193
- inputs = tokenizer("system\nYou are a music assistant.\nuser\nHow do I play a G major chord?\nassistant\n", return_tensors="pt")
194
- outputs = model.generate(**inputs, max_new_tokens=200)
195
- print(tokenizer.decode(outputs[0], skip_special_tokens=True))
196
- ```
197
-
198
- ## 🧪 Testing
199
-
200
- Run the comprehensive test suite:
201
-
202
- ```bash
203
- # Run all tests
204
- python tests/run_tests.py
205
-
206
- # Run with coverage
207
- python tests/run_tests.py --coverage
208
-
209
- # Run specific test categories
210
- pytest tests/test_music_theory_module.py -v
211
- pytest tests/test_tokenizer.py -v
212
- pytest tests/test_eq_adapter.py -v
213
-
214
- # Skip slow tests
215
- pytest -m "not slow"
216
- ```
217
-
218
- ## 📊 Benchmarking
219
-
220
- Evaluate model performance on music-specific tasks:
221
-
222
- ```bash
223
- # Evaluate music modules
224
- python benchmarks/evaluate_music_modules.py --device cpu --d_model 768
225
-
226
- # Run inference benchmarks
227
- python benchmarks/evaluate_inference.py --model_path checkpoints/touchgrass-3b --device cpu
228
- ```
229
-
230
- ## 🎛️ Configuration
231
-
232
- ### Training Configuration
233
-
234
- Edit `configs/training_config.py` to customize:
235
-
236
- - **Learning rate**: 2e-4 (3B), 1e-4 (7B)
237
- - **LoRA rank (r)**: 8-32 (higher = more capacity)
238
- - **LoRA alpha**: Typically 2×r
239
- - **Batch size**: Adjust based on GPU memory
240
- - **Gradient accumulation**: Use to simulate larger batches
241
- - **Loss weights**:
242
- - `lm_loss_weight=1.0` (primary language modeling)
243
- - `eq_loss_weight=0.1` (emotional intelligence)
244
- - `music_module_loss_weight=0.05` (specialized modules)
245
-
246
- ### Model Configuration
247
-
248
- - **TouchGrass-3B**: Based on Qwen3.5-3B-Instruct, d_model=2048, num_layers=36
249
- - **TouchGrass-7B**: Based on Qwen3.5-7B-Instruct, d_model=4096, num_layers=40
250
-
251
- ### Music Tokens
252
-
253
- The tokenizer extension adds these special tokens:
254
-
255
- **Domain tokens**: `[GUITAR]`, `[PIANO]`, `[DRUMS]`, `[VOCALS]`, `[THEORY]`, `[PRODUCTION]`
256
-
257
- **Emotion tokens**: `[FRUSTRATED]`, `[CONFUSED]`, `[EXCITED]`, `[CONFIDENT]`
258
-
259
- **Difficulty tokens**: `[EASY]`, `[MEDIUM]`, `[HARD]`
260
-
261
- **Function tokens**: `[TAB]`, `[CHORD]`, `[SCALE]`, `[INTERVAL]`, `[PROGRESSION]`
262
-
263
- **EQ tokens**: `[SIMPLIFY]`, `[ENCOURAGE]`
264
-
265
- **Music notation**: All note names (C, C#, D, etc.), chord types (m, dim, aug, 7, maj7, etc.)
266
-
267
- ## 📚 Music Domains Covered
268
-
269
- 1. **Guitar & Bass**: Tabs, chords, fingerings, techniques, tunings
270
- 2. **Piano & Keys**: Scales, arpeggios, hand positions, pedaling
271
- 3. **Drums & Percussion**: Beats, fills, rudiments, kit setup
272
- 4. **Vocals & Singing**: Range, breathing, technique, warmups
273
- 5. **Music Theory & Composition**: Scales, chords, progressions, harmony
274
- 6. **DJ & Production**: EQ, mixing, compression, arrangement
275
-
276
- ## 😌 Emotional Intelligence
277
-
278
- The EQ Adapter detects user frustration and adapts responses:
279
-
280
- - **Frustration detection**: Sigmoid output [0, 1] indicating frustration level
281
- - **Emotion classification**: 4 classes (frustrated, confused, excited, confident)
282
- - **Simplification gate**: Automatically simplifies explanations when frustration is high
283
- - **Encouragement templates**: Pre-built supportive responses
284
- - **Context-aware**: Uses conversation history to track emotional state
285
-
286
- ## 🔧 Advanced Usage
287
-
288
- ### Custom Dataset Generation
289
-
290
- ```python
291
- from TouchGrass.data.music_qa_generator import MusicQAGenerator
292
-
293
- # Create custom templates
294
- custom_templates = {
295
- "guitar": [
296
- {
297
- "system": "You are a {instrument} specialist.",
298
- "user": "How do I play {chord}?",
299
- "assistant": "Place your fingers: {fingering}"
300
- }
301
- ]
302
- }
303
-
304
- generator = MusicQAGenerator(templates=custom_templates, seed=123)
305
- dataset = generator.generate_dataset(num_samples=500)
306
- ```
307
-
308
- ### Multi-Instrument Context
309
-
310
- ```python
311
- from TouchGrass.inference.inference import TouchGrassInference
312
-
313
- model = TouchGrassInference(model_path="checkpoints/touchgrass-3b")
314
-
315
- # Switch between instruments seamlessly
316
- guitar_response = model.generate("How do I palm mute?", instrument="guitar")
317
- piano_response = model.generate("What are the scales in C major?", instrument="piano")
318
- theory_response = model.generate("Explain the circle of fifths", instrument="theory")
319
- ```
320
-
321
- ### LoRA Fine-Tuning Customization
322
-
323
- ```python
324
- from transformers import LoraConfig
325
-
326
- lora_config = LoraConfig(
327
- task_type=TaskType.CAUSAL_LM,
328
- r=32, # Rank (higher = more parameters)
329
- lora_alpha=64, # Alpha (typically 2×r)
330
- target_modules=["q_proj", "k_proj", "v_proj", "o_proj"], # Qwen attention modules
331
- lora_dropout=0.1,
332
- bias="none"
333
- )
334
- ```
335
-
336
- ## 🧩 Module Details
337
-
338
- ### Tab & Chord Module
339
-
340
- - **Input**: Hidden states + string/fret indices
341
- - **Output**:
342
- - `tab_validator`: Confidence score [0, 1] for tab validity
343
- - `difficulty`: 3-class classification (easy/medium/hard)
344
- - **Supports**: Multiple tunings (standard, drop D, open G), 6 strings, 24 frets
345
-
346
- ### Music Theory Module
347
-
348
- - **Functions**:
349
- - `get_scale_from_key(key, mode)`: Returns scale notes
350
- - `detect_chord_function(root, chord_type, key)`: Returns Roman numeral
351
- - `get_circle_of_fifths()`: Returns 12-key circle
352
- - `construct_chord(root, chord_type)`: Returns chord notes
353
- - `analyze_progression(progression, key)`: Returns functional analysis
354
- - **Knowledge**: All modes (ionian through locrian), intervals, transpositions
355
-
356
- ### Ear Training Module
357
-
358
- - **Interval identification**: 12 intervals (P1-P8)
359
- - **Song references**: Each interval linked to famous songs (Star Wars for P5, Jaws for m2, etc.)
360
- - **Solfege generation**: Do-Re-Mi for any key/mode
361
- - **Quiz generation**: Automatic interval quiz creation
362
-
363
- ### EQ Adapter
364
-
365
- - **Frustration detector**: Sigmoid output from hidden states
366
- - **Emotion classifier**: 4-way classification
367
- - **Simplification gate**: Context-aware response simplification
368
- - **Encouragement embed**: Pre-trained supportive phrases
369
-
370
- ### Songwriting Module
371
-
372
- - **Progression suggester**: By mood (8 types) and genre (8 types)
373
- - **Lyric generator**: With rhyme scheme awareness (ABAB, AABB, etc.)
374
- - **Hook generator**: Creates memorable song hooks
375
- - **Production advisor**: Instrumentation, effects, arrangement tips
376
-
377
- ## 📈 Training Tips
378
-
379
- 1. **Start small**: Use 3B variant for experimentation, 7B for production
380
- 2. **Data quality**: Ensure diverse coverage of all 10 categories
381
- 3. **Loss weights**: Default (1.0, 0.1, 0.05) work well; adjust if modules need more/less supervision
382
- 4. **LoRA rank**: Start with r=16; increase to 32 if underfitting
383
- 5. **Mixed precision**: Use `fp16` for NVIDIA, `bf16` for newer GPUs
384
- 6. **Gradient accumulation**: Essential for fitting larger batches on limited VRAM
385
- 7. **Checkpointing**: Save every 100-500 steps for safety
386
-
387
- ## 🤝 Contributing
388
-
389
- 1. Fork the repository
390
- 2. Create a feature branch
391
- 3. Add tests for new functionality
392
- 4. Ensure all tests pass (`python tests/run_tests.py`)
393
- 5. Submit a pull request
394
-
395
- ## 📄 License
396
-
397
- MIT License - see LICENSE file for details.
398
-
399
- ## 🙏 Acknowledgments
400
-
401
- - **Qwen3.5**: Base model from Alibaba Cloud
402
- - **HuggingFace**: Transformers and PEFT libraries
403
- - **Music theory**: Traditional Western music theory principles
404
- - **Song references**: Popular music culture for ear training
405
-
406
- ## 📞 Support
407
-
408
- - Issues: GitHub Issues
409
- - Discussions: GitHub Discussions
410
- - Documentation: See individual module docstrings
411
-
412
- ---
413
-
414
- **Made with ❤️ for musicians everywhere.**
415
-
416
- *Touch Grass - because even AI needs to remember to make music, not just talk about it.*
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ language:
3
+ - en
4
+ license: mit
5
+ base_model: Qwen/Qwen3.5-7B-Instruct
6
+ tags:
7
+ - music
8
+ - guitar
9
+ - piano
10
+ - drums
11
+ - vocals
12
+ - music-theory
13
+ - ear-training
14
+ - songwriting
15
+ - lora
16
+ - peft
17
+ - qwen
18
+ - eq-adapter
19
+ - matrix-corp
20
+ pipeline_tag: text-generation
21
+ library_name: transformers
22
+ model_type: touchgrass
23
+ ---
24
+
25
+ # Touch Grass 🎵
26
+
27
+ **A Lightweight Music AI Assistant Fine-Tuned from Qwen3.5**
28
+
29
+ Touch Grass is a specialized music AI assistant built by fine-tuning Qwen3.5 models (3B and 7B variants) with music-specific capabilities. It understands guitar, piano, drums, vocals, music theory, ear training, songwriting, and production—with emotional intelligence to help musicians through frustration.
30
+
31
+ ## 🌟 Features
32
+
33
+ - **Two Model Sizes**: TouchGrass-3B (CPU-friendly) and TouchGrass-7B (GPU-enhanced)
34
+ - **Music Tokenizer Extension**: Adds 21+ music-specific tokens to Qwen3.5's vocabulary
35
+ - **Five Specialized Modules**:
36
+ - 🎸 **Tab & Chord Generation**: Creates and validates guitar tabs, chord diagrams
37
+ - 🎹 **Music Theory Engine**: Scales, chords, intervals, progressions, circle of fifths
38
+ - 👂 **Ear Training**: Interval identification with song references, solfege exercises
39
+ - 😌 **EQ Adapter**: Frustration detection and emotional response adaptation
40
+ - ✍️ **Song Writing Assistant**: Chord progressions, lyrics, hooks, production tips
41
+ - **LoRA Fine-Tuning**: Efficient adaptation without full model retraining
42
+ - **HuggingFace Compatible**: Production-ready with custom config and tokenizer classes
43
+ - **Ollama Support**: Run locally with Ollama modelfiles
44
+ - **Unified Inference**: Instrument context switching (guitar, piano, drums, vocals, theory, production)
45
+ - **Synthetic Data Pipeline**: 10 categories, 80+ templates covering all music domains
46
+
47
+ ## 🏗️ Architecture
48
+
49
+ ```
50
+ TouchGrass/
51
+ ── configs/ # Model configurations
52
+ ├── touchgrass_3b_config.py # 3B variant config
53
+ │ ├── touchgrass_7b_config.py # 7B variant config
54
+ ── training_config.py # Training hyperparameters
55
+ ── tokenizer/
56
+ │ └── music_token_extension.py # Extends Qwen tokenizer with music tokens
57
+ ├── models/ # Specialized music modules
58
+ ├── tab_chord_module.py # Guitar tabs and chords
59
+ ├── music_theory_module.py # Theory knowledge
60
+ │ ├── ear_training_module.py # Ear training exercises
61
+ │ ├── eq_adapter.py # Emotional intelligence
62
+ │ └── songwriting_module.py # Song creation assistance
63
+ ├── data/
64
+ │ ├── music_qa_generator.py # Synthetic dataset generator
65
+ │ ├── chat_formatter.py # Qwen chat format converter
66
+ │ └── dataset_loader.py # PyTorch dataset
67
+ ├── training/
68
+ │ ├── losses.py # Multi-task loss functions
69
+ │ ├── trainer.py # LoRA-aware trainer
70
+ │ └── train.py # Main training entry point
71
+ ├── inference/
72
+ │ └── inference.py # Unified inference with context
73
+ ├── benchmarks/
74
+ │ ├── evaluate_music_modules.py # Module-level benchmarks
75
+ │ └── evaluate_inference.py # End-to-end inference benchmarks
76
+ ├── tests/ # Comprehensive test suite
77
+ │ ├── test_*.py # Unit tests for each module
78
+ │ ├── conftest.py # Pytest fixtures
79
+ │ └── run_tests.py # Test runner
80
+ ├── configuration_touchgrass.py # HuggingFace config class
81
+ ├── tokenization_touchgrass.py # HuggingFace tokenizer wrapper
82
+ ├── ollama_3b_modelfile # Ollama config for 3B
83
+ ├── ollama_7b_modelfile # Ollama config for 7B
84
+ └── train.py # Main training script
85
+ ```
86
+
87
+ ## 📦 Installation
88
+
89
+ ### Prerequisites
90
+
91
+ - Python 3.10+
92
+ - PyTorch 2.0+
93
+ - Transformers (HuggingFace)
94
+ - PEFT (LoRA)
95
+ - Datasets
96
+ - Pytest (for testing)
97
+
98
+ ### Setup
99
+
100
+ ```bash
101
+ # Clone the repository
102
+ cd TouchGrass
103
+
104
+ # Install dependencies
105
+ pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu
106
+ pip install transformers peft datasets accelerate tqdm pytest
107
+
108
+ # Optional: For GPU support
109
+ pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
110
+ ```
111
+
112
+ ## 🚀 Quick Start
113
+
114
+ ### 1. Generate Training Data
115
+
116
+ ```bash
117
+ python -c "
118
+ from TouchGrass.data.music_qa_generator import MusicQAGenerator
119
+ from TouchGrass.data.chat_formatter import ChatFormatter
120
+
121
+ # Generate synthetic dataset
122
+ generator = MusicQAGenerator(seed=42)
123
+ dataset = generator.generate_dataset(num_samples=1000, output_path='data/music_qa.jsonl')
124
+
125
+ # Format for Qwen
126
+ formatter = ChatFormatter()
127
+ formatted = formatter.format_dataset(dataset)
128
+ train_data, val_data = formatter.create_splits(formatted, val_size=0.1)
129
+
130
+ formatter.save_dataset(train_data, 'data/train.jsonl')
131
+ formatter.save_dataset(val_data, 'data/val.jsonl')
132
+ "
133
+ ```
134
+
135
+ ### 2. Train the Model
136
+
137
+ ```bash
138
+ # Train 3B variant
139
+ python train.py \
140
+ --base_model Qwen/Qwen3.5-3B-Instruct \
141
+ --train_data data/train.jsonl \
142
+ --val_data data/val.jsonl \
143
+ --output_dir checkpoints/touchgrass-3b \
144
+ --lora_r 16 \
145
+ --lora_alpha 32 \
146
+ --batch_size 4 \
147
+ --gradient_accumulation_steps 4 \
148
+ --learning_rate 2e-4 \
149
+ --num_epochs 3 \
150
+ --mixed_precision fp16
151
+
152
+ # Train 7B variant (requires GPU with 16GB+ VRAM)
153
+ python train.py \
154
+ --base_model Qwen/Qwen3.5-7B-Instruct \
155
+ --train_data data/train.jsonl \
156
+ --val_data data/val.jsonl \
157
+ --output_dir checkpoints/touchgrass-7b \
158
+ --lora_r 16 \
159
+ --lora_alpha 32 \
160
+ --batch_size 2 \
161
+ --gradient_accumulation_steps 8 \
162
+ --learning_rate 1e-4 \
163
+ --num_epochs 3 \
164
+ --mixed_precision bf16
165
+ ```
166
+
167
+ ### 3. Run Inference
168
+
169
+ ```python
170
+ from TouchGrass.inference.inference import TouchGrassInference
171
+
172
+ # Load model
173
+ model = TouchGrassInference(
174
+ model_path="checkpoints/touchgrass-3b",
175
+ device="cpu" # or "cuda"
176
+ )
177
+
178
+ # Single query with instrument context
179
+ response = model.generate(
180
+ prompt="How do I play a G major chord?",
181
+ instrument="guitar",
182
+ skill_level="beginner",
183
+ max_new_tokens=200
184
+ )
185
+ print(response)
186
+
187
+ # Interactive mode
188
+ model.chat(instrument="piano")
189
+ ```
190
+
191
+ ### 4. Use with Ollama
192
+
193
+ ```bash
194
+ # Create modelfile from provided template
195
+ cat ollama_3b_modelfile > Modelfile
196
+
197
+ # Build and run
198
+ ollama create touchgrass-3b -f Modelfile
199
+ ollama run touchgrass-3b "How do I play a G major chord on guitar?"
200
+ ```
201
+
202
+ ### 5. Use with HuggingFace
203
+
204
+ ```python
205
+ from transformers import AutoModelForCausalLM, AutoTokenizer
206
+
207
+ # Load with custom config and tokenizer
208
+ config = TouchGrassConfig.from_pretrained("checkpoints/touchgrass-3b")
209
+ tokenizer = TouchGrassTokenizer.from_pretrained("checkpoints/touchgrass-3b")
210
+ model = AutoModelForCausalLM.from_pretrained(
211
+ "checkpoints/touchgrass-3b",
212
+ config=config,
213
+ device_map="auto"
214
+ )
215
+
216
+ # Generate
217
+ inputs = tokenizer("system\nYou are a music assistant.\nuser\nHow do I play a G major chord?\nassistant\n", return_tensors="pt")
218
+ outputs = model.generate(**inputs, max_new_tokens=200)
219
+ print(tokenizer.decode(outputs[0], skip_special_tokens=True))
220
+ ```
221
+
222
+ ## 🧪 Testing
223
+
224
+ Run the comprehensive test suite:
225
+
226
+ ```bash
227
+ # Run all tests
228
+ python tests/run_tests.py
229
+
230
+ # Run with coverage
231
+ python tests/run_tests.py --coverage
232
+
233
+ # Run specific test categories
234
+ pytest tests/test_music_theory_module.py -v
235
+ pytest tests/test_tokenizer.py -v
236
+ pytest tests/test_eq_adapter.py -v
237
+
238
+ # Skip slow tests
239
+ pytest -m "not slow"
240
+ ```
241
+
242
+ ## 📊 Benchmarking
243
+
244
+ Evaluate model performance on music-specific tasks:
245
+
246
+ ```bash
247
+ # Evaluate music modules
248
+ python benchmarks/evaluate_music_modules.py --device cpu --d_model 768
249
+
250
+ # Run inference benchmarks
251
+ python benchmarks/evaluate_inference.py --model_path checkpoints/touchgrass-3b --device cpu
252
+ ```
253
+
254
+ ## 🎛️ Configuration
255
+
256
+ ### Training Configuration
257
+
258
+ Edit `configs/training_config.py` to customize:
259
+
260
+ - **Learning rate**: 2e-4 (3B), 1e-4 (7B)
261
+ - **LoRA rank (r)**: 8-32 (higher = more capacity)
262
+ - **LoRA alpha**: Typically 2×r
263
+ - **Batch size**: Adjust based on GPU memory
264
+ - **Gradient accumulation**: Use to simulate larger batches
265
+ - **Loss weights**:
266
+ - `lm_loss_weight=1.0` (primary language modeling)
267
+ - `eq_loss_weight=0.1` (emotional intelligence)
268
+ - `music_module_loss_weight=0.05` (specialized modules)
269
+
270
+ ### Model Configuration
271
+
272
+ - **TouchGrass-3B**: Based on Qwen3.5-3B-Instruct, d_model=2048, num_layers=36
273
+ - **TouchGrass-7B**: Based on Qwen3.5-7B-Instruct, d_model=4096, num_layers=40
274
+
275
+ ### Music Tokens
276
+
277
+ The tokenizer extension adds these special tokens:
278
+
279
+ **Domain tokens**: `[GUITAR]`, `[PIANO]`, `[DRUMS]`, `[VOCALS]`, `[THEORY]`, `[PRODUCTION]`
280
+
281
+ **Emotion tokens**: `[FRUSTRATED]`, `[CONFUSED]`, `[EXCITED]`, `[CONFIDENT]`
282
+
283
+ **Difficulty tokens**: `[EASY]`, `[MEDIUM]`, `[HARD]`
284
+
285
+ **Function tokens**: `[TAB]`, `[CHORD]`, `[SCALE]`, `[INTERVAL]`, `[PROGRESSION]`
286
+
287
+ **EQ tokens**: `[SIMPLIFY]`, `[ENCOURAGE]`
288
+
289
+ **Music notation**: All note names (C, C#, D, etc.), chord types (m, dim, aug, 7, maj7, etc.)
290
+
291
+ ## 📚 Music Domains Covered
292
+
293
+ 1. **Guitar & Bass**: Tabs, chords, fingerings, techniques, tunings
294
+ 2. **Piano & Keys**: Scales, arpeggios, hand positions, pedaling
295
+ 3. **Drums & Percussion**: Beats, fills, rudiments, kit setup
296
+ 4. **Vocals & Singing**: Range, breathing, technique, warmups
297
+ 5. **Music Theory & Composition**: Scales, chords, progressions, harmony
298
+ 6. **DJ & Production**: EQ, mixing, compression, arrangement
299
+
300
+ ## 😌 Emotional Intelligence
301
+
302
+ The EQ Adapter detects user frustration and adapts responses:
303
+
304
+ - **Frustration detection**: Sigmoid output [0, 1] indicating frustration level
305
+ - **Emotion classification**: 4 classes (frustrated, confused, excited, confident)
306
+ - **Simplification gate**: Automatically simplifies explanations when frustration is high
307
+ - **Encouragement templates**: Pre-built supportive responses
308
+ - **Context-aware**: Uses conversation history to track emotional state
309
+
310
+ ## 🔧 Advanced Usage
311
+
312
+ ### Custom Dataset Generation
313
+
314
+ ```python
315
+ from TouchGrass.data.music_qa_generator import MusicQAGenerator
316
+
317
+ # Create custom templates
318
+ custom_templates = {
319
+ "guitar": [
320
+ {
321
+ "system": "You are a {instrument} specialist.",
322
+ "user": "How do I play {chord}?",
323
+ "assistant": "Place your fingers: {fingering}"
324
+ }
325
+ ]
326
+ }
327
+
328
+ generator = MusicQAGenerator(templates=custom_templates, seed=123)
329
+ dataset = generator.generate_dataset(num_samples=500)
330
+ ```
331
+
332
+ ### Multi-Instrument Context
333
+
334
+ ```python
335
+ from TouchGrass.inference.inference import TouchGrassInference
336
+
337
+ model = TouchGrassInference(model_path="checkpoints/touchgrass-3b")
338
+
339
+ # Switch between instruments seamlessly
340
+ guitar_response = model.generate("How do I palm mute?", instrument="guitar")
341
+ piano_response = model.generate("What are the scales in C major?", instrument="piano")
342
+ theory_response = model.generate("Explain the circle of fifths", instrument="theory")
343
+ ```
344
+
345
+ ### LoRA Fine-Tuning Customization
346
+
347
+ ```python
348
+ from transformers import LoraConfig
349
+
350
+ lora_config = LoraConfig(
351
+ task_type=TaskType.CAUSAL_LM,
352
+ r=32, # Rank (higher = more parameters)
353
+ lora_alpha=64, # Alpha (typically 2×r)
354
+ target_modules=["q_proj", "k_proj", "v_proj", "o_proj"], # Qwen attention modules
355
+ lora_dropout=0.1,
356
+ bias="none"
357
+ )
358
+ ```
359
+
360
+ ## 🧩 Module Details
361
+
362
+ ### Tab & Chord Module
363
+
364
+ - **Input**: Hidden states + string/fret indices
365
+ - **Output**:
366
+ - `tab_validator`: Confidence score [0, 1] for tab validity
367
+ - `difficulty`: 3-class classification (easy/medium/hard)
368
+ - **Supports**: Multiple tunings (standard, drop D, open G), 6 strings, 24 frets
369
+
370
+ ### Music Theory Module
371
+
372
+ - **Functions**:
373
+ - `get_scale_from_key(key, mode)`: Returns scale notes
374
+ - `detect_chord_function(root, chord_type, key)`: Returns Roman numeral
375
+ - `get_circle_of_fifths()`: Returns 12-key circle
376
+ - `construct_chord(root, chord_type)`: Returns chord notes
377
+ - `analyze_progression(progression, key)`: Returns functional analysis
378
+ - **Knowledge**: All modes (ionian through locrian), intervals, transpositions
379
+
380
+ ### Ear Training Module
381
+
382
+ - **Interval identification**: 12 intervals (P1-P8)
383
+ - **Song references**: Each interval linked to famous songs (Star Wars for P5, Jaws for m2, etc.)
384
+ - **Solfege generation**: Do-Re-Mi for any key/mode
385
+ - **Quiz generation**: Automatic interval quiz creation
386
+
387
+ ### EQ Adapter
388
+
389
+ - **Frustration detector**: Sigmoid output from hidden states
390
+ - **Emotion classifier**: 4-way classification
391
+ - **Simplification gate**: Context-aware response simplification
392
+ - **Encouragement embed**: Pre-trained supportive phrases
393
+
394
+ ### Songwriting Module
395
+
396
+ - **Progression suggester**: By mood (8 types) and genre (8 types)
397
+ - **Lyric generator**: With rhyme scheme awareness (ABAB, AABB, etc.)
398
+ - **Hook generator**: Creates memorable song hooks
399
+ - **Production advisor**: Instrumentation, effects, arrangement tips
400
+
401
+ ## 📈 Training Tips
402
+
403
+ 1. **Start small**: Use 3B variant for experimentation, 7B for production
404
+ 2. **Data quality**: Ensure diverse coverage of all 10 categories
405
+ 3. **Loss weights**: Default (1.0, 0.1, 0.05) work well; adjust if modules need more/less supervision
406
+ 4. **LoRA rank**: Start with r=16; increase to 32 if underfitting
407
+ 5. **Mixed precision**: Use `fp16` for NVIDIA, `bf16` for newer GPUs
408
+ 6. **Gradient accumulation**: Essential for fitting larger batches on limited VRAM
409
+ 7. **Checkpointing**: Save every 100-500 steps for safety
410
+
411
+ ## 🤝 Contributing
412
+
413
+ 1. Fork the repository
414
+ 2. Create a feature branch
415
+ 3. Add tests for new functionality
416
+ 4. Ensure all tests pass (`python tests/run_tests.py`)
417
+ 5. Submit a pull request
418
+
419
+ ## 📄 License
420
+
421
+ MIT License - see LICENSE file for details.
422
+
423
+ ## 🙏 Acknowledgments
424
+
425
+ - **Qwen3.5**: Base model from Alibaba Cloud
426
+ - **HuggingFace**: Transformers and PEFT libraries
427
+ - **Music theory**: Traditional Western music theory principles
428
+ - **Song references**: Popular music culture for ear training
429
+
430
+ ## 📞 Support
431
+
432
+ - Issues: GitHub Issues
433
+ - Discussions: GitHub Discussions
434
+ - Documentation: See individual module docstrings
435
+
436
+ ---
437
+
438
+ **Made with ❤️ for musicians everywhere.**
439
+
440
+ *Touch Grass - because even AI needs to remember to make music, not just talk about it.*