lllindsey0615 commited on
Commit
cb6aae7
·
1 Parent(s): 6eb2dcc

initial commit

Browse files
Files changed (3) hide show
  1. Dockerfile +35 -0
  2. app.py +143 -0
  3. requirements.txt +17 -0
Dockerfile ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use Python 3.11
2
+ FROM python:3.11
3
+
4
+ # Set working directory
5
+ WORKDIR /app
6
+
7
+ # Install system dependencies
8
+ RUN apt-get update && apt-get install -y \
9
+ git \
10
+ libsndfile1 \
11
+ fluid-soundfont-gm \
12
+ && rm -rf /var/lib/apt/lists/*
13
+
14
+ # Upgrade pip before installing dependencies
15
+ RUN pip install --upgrade pip
16
+
17
+ # Copy and install Python dependencies first (before cloning anticipation)
18
+ COPY requirements.txt .
19
+ RUN pip install --no-cache-dir -r requirements.txt
20
+
21
+ # Clone and install Anticipation Music Transformer (AMT)
22
+ RUN git clone https://github.com/jthickstun/anticipation.git
23
+
24
+ # Install AMT dependencies separately to avoid conflicts
25
+ RUN pip install -r anticipation/requirements.txt && \
26
+ pip install ./anticipation
27
+
28
+ # Debugging: Check installed packages
29
+ RUN pip list
30
+
31
+ # Copy the application files into the container
32
+ COPY . .
33
+
34
+ # Run the Gradio app
35
+ CMD ["python", "app.py"]
app.py ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import spaces # Enables ZeroGPU on Hugging Face
3
+ from transformers import AutoModelForCausalLM
4
+ from anticipation.sample import generate
5
+ from anticipation.convert import events_to_midi, midi_to_events
6
+ from anticipation import ops
7
+ from anticipation.tokenize import extract_instruments
8
+ import torch
9
+ from pyharp import *
10
+ from safetensors.torch import load_file
11
+ import os
12
+
13
+
14
+ #Model Choices
15
+ SMALL_MODEL = "stanford-crfm/music-small-800k"
16
+ MEDIUM_MODEL = "stanford-crfm/music-medium-800k"
17
+ LARGE_MODEL = "stanford-crfm/music-large-800k"
18
+
19
+ # === Model Card ===
20
+ model_card = ModelCard(
21
+ name="Anticipatory Music Transformer",
22
+ description="Using Anticipatory Music Transformer (AMT) to generate accompaniment for a given MIDI file with selected melody.",
23
+ author="John Thickstun, David Hall, Chris Donahue, Percy Liang",
24
+ tags=["midi", "generation", "accompaniment"],
25
+ midi_in=True,
26
+ midi_out=True
27
+ )
28
+
29
+ model_cache = {}
30
+
31
+ '''
32
+ def load_amt_model(model_choice):
33
+ """Loads and caches the AMT model inside the worker process."""
34
+ if model_choice in model_cache:
35
+ return model_cache[model_choice]
36
+
37
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
38
+ model = AutoModelForCausalLM.from_pretrained(model_choice).to(device)
39
+
40
+ model_cache[model_choice] = model
41
+ return model
42
+ '''
43
+
44
+ def load_amt_model(model_choice):
45
+ """Loads and caches the AMT model inside the worker process."""
46
+ if model_choice in model_cache:
47
+ return model_cache[model_choice]
48
+
49
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
50
+
51
+ if model_choice == LARGE_MODEL:
52
+ # Large model uses safetensors
53
+ model_dir = "./tmp_music_large"
54
+ os.makedirs(model_dir, exist_ok=True)
55
+
56
+ print(f"Loading {LARGE_MODEL} from safetensors format...")
57
+ model = AutoModelForCausalLM.from_pretrained(
58
+ LARGE_MODEL,
59
+ torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
60
+ low_cpu_mem_usage=True
61
+ ).to(device)
62
+ else:
63
+ # Small and medium use standard PyTorch .bin format
64
+ print(f"Loading {model_choice} from standard format...")
65
+ model = AutoModelForCausalLM.from_pretrained(model_choice).to(device)
66
+
67
+ model_cache[model_choice] = model
68
+ return model
69
+
70
+
71
+
72
+
73
+ @spaces.GPU
74
+ def generate_accompaniment(midi_file, model_choice, selected_midi_program, history_length):
75
+ """Generates accompaniment for the entire MIDI input, conditioned on the user-selected history length."""
76
+
77
+ model = load_amt_model(model_choice)
78
+ events = midi_to_events(midi_file.name)
79
+ total_time = round(ops.max_time(events, seconds=True))
80
+
81
+ # Extract melody line using the selected MIDI program number
82
+ events, melody = extract_instruments(events, [selected_midi_program])
83
+
84
+ if not melody:
85
+ return None, "⚠️ Please select a valid MIDI program that contains events."
86
+
87
+ history = ops.clip(events, 0, history_length, clip_duration=False)
88
+
89
+ # Generate accompaniment for the remaining duration
90
+ accompaniment = generate(
91
+ model,
92
+ history_length, # Start generating after user-defined history length
93
+ total_time, # Generate for the full remaining duration
94
+ inputs=history,
95
+ controls=melody,
96
+ top_p=0.95,
97
+ debug=False
98
+ )
99
+
100
+ # Combine the accompaniment with the melody
101
+ output_events = ops.clip(ops.combine(accompaniment, melody), 0, total_time, clip_duration=True)
102
+
103
+ # Convert back to MIDI
104
+ output_midi = "generated_accompaniment_huggingface.mid"
105
+ mid = events_to_midi(output_events)
106
+ mid.save(output_midi)
107
+
108
+ return output_midi, None
109
+
110
+
111
+ def process_fn(input_midi, model_choice, selected_midi_program, history_length):
112
+ """Processes the input and runs AMT to generate accompaniment for the full MIDI file."""
113
+ output_midi, error_message = generate_accompaniment(input_midi, model_choice, selected_midi_program, history_length)
114
+
115
+ if error_message:
116
+ return None, {"message": error_message}
117
+
118
+ output_labels = LabelList()
119
+ return output_midi, output_labels
120
+
121
+
122
+ # === Build HARP gradioEndpoint ===
123
+ with gr.Blocks() as demo:
124
+ components = [
125
+ gr.Dropdown(
126
+ choices=[SMALL_MODEL, MEDIUM_MODEL, LARGE_MODEL],
127
+ value=MEDIUM_MODEL,
128
+ label="Select AMT Model (Faster vs. Higher Quality)"
129
+ ),
130
+ gr.Slider(0, 127, step=1, value=1, label="Select Melody Instrument (MIDI Program Number)"),
131
+ gr.Slider(1, 10, step=1, value=5, label="Select History Length (seconds)")
132
+ ]
133
+
134
+ # Wrap in PyHARP
135
+ app = build_endpoint(
136
+ model_card=model_card,
137
+ components=components,
138
+ process_fn=process_fn)
139
+
140
+ # Launch PyHARP App
141
+ demo.launch(share=True, show_error=True, debug=True)
142
+
143
+
requirements.txt ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ -e git+https://github.com/TEAMuP-dev/pyharp.git#egg=pyharp
2
+ demucs
3
+ dora-search
4
+ einops
5
+ julius>=0.2.3
6
+ lameenc>=1.2
7
+ openunmix
8
+ pyyaml
9
+ tqdm
10
+ torch>=1.8.1, <2.1
11
+ torchaudio>=0.8, <2.1
12
+ diffq>=0.2.1
13
+ ffmpeg
14
+ numpy<2
15
+ scipy
16
+ soundfile
17
+ hydra-core>=1.1