Views
No views yet
Modèle : LLaMA 3.2 3B fine-tuné · LoRA r=32 · QLoRA 4-bit
Spécialité : Génération AMT multi-instrument (DRUMS, BASS, LEAD, CHORDS, AMB)
Source : Slakh2100 — ~50 000 exemples · 6 genres · BPM variable
Format de sortie : Séquence AMT delta-time multi-canal → convertible en MIDI multi-track
Below is an instruction that describes a music task.
### Instruction:
{INSTRUCTION}
### Response:
<MUSIC><MUSIC> et s'arrête sur </s>.| Tag | Valeurs | Description |
|---|---|---|
[TASK:X] | GEN JAM FIM COPILOT | Type de tâche (voir §4) |
[GENRE:X] | POP_ROCK JAZZ ELECTRONIC CLASSICAL FOLK LATIN | Style musical |
[BPM:X] | 40→240 (multiple de 5) | Tempo — ex: 70, 90, 120, 128, 140 |
[MOOD:X] | ENERGETIC CHILL DARK UPLIFTING MELANCHOLIC GROOVY EPIC DREAMY | Ambiance |
[BARS:X] | 1→16 | Nombre de mesures cibles |
[DENSITY:X] | SPARSE NORMAL DENSE | Densité de notes |
[COMPLEXITY:X] | SIMPLE NORMAL COMPLEX | Richesse harmonique et polyphonie |
| Tag | Valeurs | Description |
|---|---|---|
[KEY:X_Y] | 0→11 + MAJOR/MINOR | Tonalité cible |
[KEY_PRE:X_Y] | idem | Tonalité avant (FIM) |
[KEY_SUF:X_Y] | idem | Tonalité après (FIM) |
| Chiffre | Note | Chiffre | Note |
|---|---|---|---|
| 0 | Do (C) | 6 | Fa# / Sol♭ |
| 1 | Do# / Ré♭ | 7 | Sol (G) |
| 2 | Ré (D) | 8 | Sol# / La♭ |
| 3 | Ré# / Mi♭ | 9 | La (A) |
| 4 | Mi (E) | 10 | La# / Si♭ |
| 5 | Fa (F) | 11 | Si (B) |
| MOOD | Vélocité min | Vélocité max | Usage typique |
|---|---|---|---|
ENERGETIC | 80 | 127 | Rock, techno, festival |
EPIC | 85 | 127 | Cinématique, orchestral |
GROOVY | 70 | 115 | Funk, groove, danse |
UPLIFTING | 65 | 110 | Pop positive |
CHILL | 40 | 85 | Lo-fi, jazz calme |
DREAMY | 30 | 75 | Ambient, electronica douce |
MELANCHOLIC | 35 | 80 | Ballades, blues |
DARK | 45 | 95 | Metal, techno sombre |
| Canal | Code | Rôle | Programme GM | Instruments typiques |
|---|---|---|---|---|
IP_9 | DRUMS | Percussion | Standard Kit | Kick, snare, hihat, cymbale |
IP_1 | BASS | Basse | Acoustic Bass (32) | Basse électrique, contrebasse |
IP_0 | LEAD | Mélodie | Grand Piano (0) | Guitare solo, saxophone, synth lead |
IP_2 | CHORDS | Harmonie | String Ensemble (48) | Piano, guitare rythmique, orgue |
IP_3 | AMB | Nappes | Pad Warm (91) | Strings, pads de synthé |
[TASK:GEN][GENRE:JAZZ][BPM:110][MOOD:CHILL][BARS:8][DENSITY:NORMAL][COMPLEXITY:NORMAL][TASK:GEN][GENRE:POP_ROCK][BPM:120][MOOD:ENERGETIC][BARS:16][DENSITY:DENSE][COMPLEXITY:NORMAL][KEY:0_MAJOR][TASK:JAM][GENRE:ELECTRONIC][BPM:128][MOOD:DARK][BARS:8][DENSITY:NORMAL][COMPLEXITY:NORMAL][KEY:9_MINOR] /CONTEXT {AMT_SEQUENCE}[KEY:X_Y][TASK:FIM][GENRE:JAZZ][BPM:100][MOOD:MELANCHOLIC][BARS:12][DENSITY:SPARSE][COMPLEXITY:SIMPLE]
[KEY_PRE:9_MINOR][KEY_SUF:2_MINOR]
/SUF {AMT_SEQUENCE_FIN}
/PRE {AMT_SEQUENCE_DEBUT}⚠️ Ordre critique :/SUFprécède toujours/PREdans l'instruction.
[CONFIRME:9_MINOR->2_MINOR] /TARGET {AMT_SEQUENCE_GENEREE} </s>[CONFIRME:X->Y] : transition harmonique détectée et confirmée/TARGET : séquence générée pour combler le trou[TASK:COPILOT][GENRE:JAZZ][BPM:100][MOOD:CHILL][BARS:8][DENSITY:NORMAL][COMPLEXITY:NORMAL][KEY:0_MAJOR]
/CONTEXT {AMT_SEQUENCE_INSTRUMENTS_FOURNIS}
/TARGET {INSTRUMENTS_A_GENERER}/TARGET :| Situation | /TARGET |
|---|---|
| J'ai drums+chords, je veux basse+lead | BASS,LEAD |
| J'ai basse+lead, je veux chords+nappes | CHORDS,AMB |
| J'ai tout sauf drums | DRUMS |
A_{delta} D_{duration} IP_{canal}_{pitch}_{velocity}| Champ | Description |
|---|---|
A_{delta} | Délai depuis la note précédente (ticks, grille 24) · A_0 = simultané |
D_{duration} | Durée de la note (ticks) |
IP_{ch}_{pitch}_{vel} | Canal + hauteur MIDI (0-127) + vélocité (0-127) |
| Ticks | Durée | Exemple |
|---|---|---|
| 24 | Triples croches (1/32) | D_24 |
| 48 | Double-croche (1/16) | D_48 |
| 96 | Croche (1/8) | D_96 |
| 192 | Noire (1/4) | D_192 |
| 384 | Blanche (1/2) | D_384 |
| 480 | Noire + liée | D_480 |
| 960 | Ronde (1/1) | D_960 |
| 1920 | Ronde double (max) | D_1920 |
A_0 D_24 IP_9_36_85 ← Kick (C2) — temps fort
A_0 D_480 IP_1_40_75 ← Basse (E2) — tenue longue
A_0 D_960 IP_2_60_62 ← Do (C4) chord
A_0 D_960 IP_2_64_58 ← Mi (E4) chord
A_0 D_960 IP_2_67_55 ← Sol (G4) chord
A_192 D_24 IP_9_42_70 ← Snare (F#2) — temps faible
A_192 D_480 IP_0_67_68 ← Mélodie Sol (G4)
A_288 D_24 IP_9_42_65 ← Snare1instruction = (
2 "[TASK:GEN][GENRE:JAZZ][BPM:110][MOOD:CHILL]"
3 "[BARS:8][DENSITY:NORMAL][COMPLEXITY:NORMAL][KEY:9_MINOR]"
4)1instruction = (
2 "[TASK:GEN][GENRE:ELECTRONIC][BPM:128][MOOD:DARK]"
3 "[BARS:16][DENSITY:DENSE][COMPLEXITY:COMPLEX]"
4)1instruction = (
2 "[TASK:GEN][GENRE:POP_ROCK][BPM:120][MOOD:ENERGETIC]"
3 "[BARS:8][DENSITY:NORMAL][COMPLEXITY:NORMAL][KEY:0_MAJOR]"
4)1context_amt = (
2 "A_0 D_24 IP_9_36_85 A_0 D_480 IP_1_40_75 "
3 "A_0 D_960 IP_2_60_62 A_0 D_960 IP_2_64_58 "
4 "A_192 D_24 IP_9_42_70 A_192 D_480 IP_0_67_68 "
5 "A_288 D_24 IP_9_42_65 A_288 D_240 IP_0_65_65"
6)
7
8instruction = (
9 f"[TASK:JAM][GENRE:JAZZ][BPM:110][MOOD:CHILL]"
10 f"[BARS:8][DENSITY:NORMAL][COMPLEXITY:NORMAL]"
11 f"[KEY:9_MINOR] /CONTEXT {context_amt}"
12)1pre_amt = (
2 "A_0 D_960 IP_2_57_60 A_0 D_960 IP_2_60_55 A_0 D_960 IP_2_64_52 "
3 "A_0 D_24 IP_9_36_65 A_480 D_24 IP_9_42_62 "
4 "A_0 D_480 IP_1_45_68 A_480 D_480 IP_1_45_65 "
5 "A_0 D_960 IP_0_69_60"
6)
7suf_amt = (
8 "A_0 D_960 IP_2_62_60 A_0 D_960 IP_2_65_55 A_0 D_960 IP_2_69_52 "
9 "A_0 D_24 IP_9_36_65 A_480 D_24 IP_9_42_62 "
10 "A_0 D_480 IP_1_50_68 A_480 D_480 IP_1_50_65 "
11 "A_0 D_960 IP_0_74_60"
12)
13
14instruction = (
15 f"[TASK:FIM][GENRE:JAZZ][BPM:90][MOOD:MELANCHOLIC]"
16 f"[BARS:12][DENSITY:SPARSE][COMPLEXITY:SIMPLE]"
17 f"[KEY_PRE:9_MINOR][KEY_SUF:2_MINOR]"
18 f" /SUF {suf_amt} /PRE {pre_amt}"
19)1context_amt = (
2 # Drums
3 "A_0 D_24 IP_9_36_65 A_0 D_24 IP_9_42_60 "
4 "A_480 D_24 IP_9_36_68 A_480 D_24 IP_9_42_62 "
5 "A_480 D_24 IP_9_36_65 A_480 D_24 IP_9_46_58 "
6 # Chords (Do maj 7 : C E G B)
7 "A_0 D_960 IP_2_60_62 A_0 D_960 IP_2_64_58 "
8 "A_0 D_960 IP_2_67_60 A_0 D_960 IP_2_71_55"
9)
10
11instruction = (
12 f"[TASK:COPILOT][GENRE:JAZZ][BPM:100][MOOD:CHILL]"
13 f"[BARS:8][DENSITY:NORMAL][COMPLEXITY:NORMAL]"
14 f"[KEY:0_MAJOR]"
15 f" /CONTEXT {context_amt}"
16 f" /TARGET BASS,LEAD"
17)| Usage | Temperature | top_p | repetition_penalty | Notes |
|---|---|---|---|---|
| Studio / précision | 0.8 | 0.90 | 1.5 | Académique, fidèle |
| Usage standard | 1.1 | 0.92 | 1.8 | Recommandé |
| Expérimental | 1.3 | 0.95 | 2.0 | Surprenant, parfois chaotique |
| Longue durée (>60s) | 1.0 | 0.90 | 2.0 | Évite les répétitions |
1import re, mido
2from mido import MidiFile, MidiTrack, Message, MetaMessage
3from collections import defaultdict
4
5TICKS_PER_BEAT = 96
6AMT_SCALE = TICKS_PER_BEAT / 24 # 1 tick AMT = 4 ticks MIDI
7TOKEN_RE = re.compile(r'\b(A_\d+|D_\d+|IP_\d+_\d+_\d+)\b')
8
9# Canal AMT → canal MIDI + programme GM
10CHANNEL_CONFIG = {
11 9: {"midi_ch": 9, "program": 0, "name": "Drums"}, # Kit batterie
12 1: {"midi_ch": 1, "program": 32, "name": "Bass"}, # Acoustic Bass
13 0: {"midi_ch": 0, "program": 0, "name": "Lead"}, # Grand Piano
14 2: {"midi_ch": 2, "program": 48, "name": "Chords"}, # Strings
15 3: {"midi_ch": 3, "program": 91, "name": "Ambient"}, # Pad Warm
16}
17
18def amt_to_midi_multitrack(amt_text: str, bpm: int, output_path: str):
19 tokens = TOKEN_RE.findall(amt_text)
20 notes, cursor = [], 0
21 i = 0
22 while i + 2 < len(tokens):
23 a, d, ip = tokens[i], tokens[i+1], tokens[i+2]
24 if a.startswith("A_") and d.startswith("D_") and ip.startswith("IP_"):
25 cursor += int(a[2:])
26 dur = int(d[2:])
27 _, ch, pitch, vel = ip.split("_")
28 notes.append((cursor, dur, int(ch), int(pitch), int(vel)))
29 i += 3
30 else:
31 i += 1
32
33 mid = MidiFile(type=1, ticks_per_beat=TICKS_PER_BEAT)
34
35 # Track 0 : tempo
36 t0 = MidiTrack()
37 mid.tracks.append(t0)
38 t0.append(MetaMessage("set_tempo", tempo=mido.bpm2tempo(bpm), time=0))
39
40 # Regrouper par canal AMT
41 channels_map = defaultdict(list)
42 for onset, dur, amt_ch, pitch, vel in notes:
43 t_on = int(onset * AMT_SCALE)
44 t_off = int((onset + dur) * AMT_SCALE)
45 channels_map[amt_ch].append((t_on, t_off, pitch, vel))
46
47 # Créer une piste MIDI par canal
48 for amt_ch, ch_notes in sorted(channels_map.items()):
49 cfg = CHANNEL_CONFIG.get(amt_ch, {"midi_ch": amt_ch % 16, "program": 0, "name": "Unknown"})
50 midi_ch = cfg["midi_ch"]
51 track = MidiTrack()
52 mid.tracks.append(track)
53
54 if midi_ch != 9: # Pas de program_change pour drums
55 track.append(Message("program_change", channel=midi_ch,
56 program=cfg["program"], time=0))
57
58 events = []
59 for t_on, t_off, pitch, vel in ch_notes:
60 events.append((t_on, "note_on", pitch, vel))
61 events.append((t_off, "note_off", pitch, 0))
62
63 events.sort(key=lambda e: (e[0], 0 if e[1] == "note_off" else 1))
64 current_tick = 0
65 for abs_tick, msg_type, pitch, vel in events:
66 delta = abs_tick - current_tick
67 track.append(Message(msg_type, channel=midi_ch,
68 note=pitch, velocity=vel, time=delta))
69 current_tick = abs_tick
70
71 mid.save(output_path)
72 return True
73
74# Utilisation
75amt_to_midi_multitrack(amt, bpm=110, output_path="sortie.mid")| Capacité | MULTI | CLASSICAL |
|---|---|---|
| Multi-instrument | ✅ 5 canaux | ❌ Piano only (IP_2) |
| BPM variable | ✅ 40-240 | ⚠️ 120 uniquement |
| Tag GENRE | ✅ 6 genres | ❌ |
| Tag MOOD | ✅ 8 humeurs | ❌ |
| Tag BARS | ✅ 1-16 | ✅ 4/8/12/16/32 |
| COPILOT | ✅ | ⚠️ Non ré-entraîné |
| Piano classique | ⚠️ Généraliste | ✅ Spécialisé |
| Dynamiques fin | ⚠️ | ✅ |