Add pipeline tag and library name

#1
by nielsr HF staff - opened
Files changed (1) hide show
  1. README.md +181 -2
README.md CHANGED
@@ -2,6 +2,8 @@
2
  license: mit
3
  tags:
4
  - music
 
 
5
  ---
6
 
7
  # 🎡 NotaGen: Advancing Musicality in Symbolic Music Generation with Large Language Model Training Paradigms
@@ -79,8 +81,183 @@ Inspired by Deepseek-R1, we further optimized the training procedures of NotaGen
79
  - After RL, we utilized the resulting checkpoint to gather a new set of post-training data. Starting from the pre-trained checkpoint, we conducted another round of post-training, fine-tuning, and reinforcement learning.
80
 
81
 
82
- For implementation of pre-training, fine-tuning and reinforcement learning on NotaGen, please view our [github page](https://github.com/ElectricAlexis/NotaGen).
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
  ## πŸ“š Citation
86
 
@@ -98,4 +275,6 @@ If you find **NotaGen** or **CLaMP-DPO** useful in your work, please cite our pa
98
  }
99
  ```
100
 
101
-
 
 
 
2
  license: mit
3
  tags:
4
  - music
5
+ pipeline_tag: text-to-audio
6
+ library_name: transformers
7
  ---
8
 
9
  # 🎡 NotaGen: Advancing Musicality in Symbolic Music Generation with Large Language Model Training Paradigms
 
81
  - After RL, we utilized the resulting checkpoint to gather a new set of post-training data. Starting from the pre-trained checkpoint, we conducted another round of post-training, fine-tuning, and reinforcement learning.
82
 
83
 
84
+ ## 🎹 Local Gradio Demo
85
 
86
+ We developed a local Gradio demo for NotaGen-X. You can input **"Period-Composer-Instrumentation"** as the prompt to have NotaGen generate music!
87
+
88
+ <p align="center">
89
+ <img src="gradio/illustration.png" alt="NotaGen Gradio Demo">
90
+ </p>
91
+
92
+ Deploying NotaGen-X inference locally requires at least 40GB of GPU memory. For implementation details, please view [gradio/README.md](https://github.com/ElectricAlexis/NotaGen/blob/main/gradio/README.md). We are also working on developing an online demo.
93
+
94
+
95
+ ## πŸ› οΈ Data Pre-processing & Post-processing
96
+
97
+ For converting **ABC notation** files from / to **MusicXML** files, please view [data/README.md](https://github.com/ElectricAlexis/NotaGen/blob/main/data/README.md) for instructions.
98
+
99
+ To illustrate the specific data format, we provide a small dataset of **Schubert's lieder** compositions from the [OpenScore Lieder](https://github.com/OpenScore/Lieder), which includes:
100
+ - πŸ—‚οΈ Interleaved ABC folders
101
+ - πŸ—‚οΈ Augmented ABC folders
102
+ - πŸ“„ Data index files for training and evaluation
103
+
104
+ You can download it [here](https://drive.google.com/drive/folders/1iVLkcywzXGcHFodce9nDQyEmK4UDmBtY?usp=sharing) and put it under ```data/```.
105
+
106
+ In the instructions of **Fine-tuning** and **Reinforcement Learning** below, we will use this dataset as an example of our implementation. **It won't include the "period-composer-instrumentation" conditioning**, just for showing how to adapt the pretrained NotaGen to a specific music style.
107
+
108
+
109
+ ## 🧠 Pre-train
110
+ If you want to use your own data to pre-train a blank **NotaGen** model, please:
111
+ 1. Preprocess the data and generate the data index files following the instructions in [data/README.md](https://github.com/ElectricAlexis/NotaGen/blob/main/data/README.md)
112
+ 2. Modify the parameters in ```pretrain/config.py```
113
+
114
+ Use this command for pre-training:
115
+ ```bash
116
+ cd pretrain/
117
+ accelerate launch --multi_gpu --mixed_precision fp16 train-gen.py
118
+ ```
119
+
120
+ ## 🎯 Fine-tune
121
+
122
+ Here we give an example on fine-tuning **NotaGen-large** with the **Schubert's lieder** data mentioned above.
123
+
124
+ **Notice:** The use of **NotaGen-large** requires at least **40GB of GPU memory** for training and inference. Alternatively, you may use **NotaGen-small** or **NotaGen-medium** and change the configuration of models in ```finetune/config.py```.
125
+
126
+ ### Configuration
127
+ - In ```finetune/config.py```:
128
+ - Modify the ```DATA_TRAIN_INDEX_PATH``` and ```DATA_EVAL_INDEX_PATH```:
129
+ ```python
130
+ # Configuration for the data
131
+ DATA_TRAIN_INDEX_PATH = "../data/schubert_augmented_train.jsonl"
132
+ DATA_EVAL_INDEX_PATH = "../data/schubert_augmented_eval.jsonl"
133
+ ```
134
+ - Download pre-trained NotaGen weights, and modify the ```PRETRAINED_PATH```:
135
+ ```python
136
+ PRETRAINED_PATH = "../pretrain/weights_notagen_pretrain_p_size_16_p_length_1024_p_layers_20_c_layers_6_h_size_1280_lr_0.0001_batch_4.pth" # Use NotaGen-large
137
+ ```
138
+ - ```EXP_TAG``` is for differentiating the models. It will be integrated into the ckpt's name. Here we set it to ```schubert```.
139
+ - You can also modify other parameters like the learning rate.
140
+
141
+ ### Execution
142
+ Use this command for fine-tuning:
143
+ ```bash
144
+ cd finetune/
145
+ CUDA_VISIBLE_DEVICES=0 python train-gen.py
146
+ ```
147
+
148
+ ## πŸš€ Reinforcement Learning (CLaMP-DPO)
149
+
150
+ Here we give an example on how to use **CLaMP-DPO** to enhance the model fine-tuned with **Schubert's lieder** data.
151
+
152
+ ### βš™οΈ CLaMP 2 Setup
153
+
154
+ Download model weights and put them under the ```clamp2/```folder:
155
+ - [CLaMP 2 Model Weights](https://huggingface.co/sander-wood/clamp2/blob/main/weights_clamp2_h_size_768_lr_5e-05_batch_128_scale_1_t_length_128_t_model_FacebookAI_xlm-roberta-base_t_dropout_True_m3_True.pth)
156
+ - [M3 Model Weights](https://huggingface.co/sander-wood/clamp2/blob/main/weights_m3_p_size_64_p_length_512_t_layers_3_p_layers_12_h_size_768_lr_0.0001_batch_16_mask_0.45.pth)
157
+
158
+ ### πŸ” Extract Ground Truth Features
159
+ Modify ```input_dir``` and ```output_dir``` in ```clamp2/extract_clamp2.py```:
160
+ ```python
161
+ input_dir = '../data/schubert_interleaved' # interleaved abc folder
162
+ output_dir = 'feature/schubert_interleaved' # feature folder
163
+ ```
164
+ Extract the features:
165
+ ```
166
+ cd clamp2/
167
+ python extract_clamp2.py
168
+ ```
169
+
170
+ ### πŸ”„ CLaMP-DPO
171
+
172
+ Here we give an example of an iteration of **CLaMP-DPO** from the initial model fine-tuned on **Schubert's lieder** data.
173
+
174
+ #### 1. Inference
175
+ - Modify the ```INFERENCE_WEIGHTS_PATH``` to path of the fine-tuned weights and ```NUM_SAMPLES``` to generate in ```inference/config.py```:
176
+ ```python
177
+ INFERENCE_WEIGHTS_PATH = '../finetune/weights_notagen_schubert_p_size_16_p_length_1024_p_layers_20_c_layers_6_h_size_1280_lr_1e-05_batch_1.pth'
178
+ NUM_SAMPLES = 1000
179
+ ```
180
+ - Inference:
181
+ ```
182
+ cd inference/
183
+ python inference.py
184
+ ```
185
+ This will generate an ```output/```folder with two subfolders: ```original``` and ```interleaved```. The ```original/``` subdirectory stores the raw inference outputs from the model, while the ```interleaved/``` subdirectory contains data post-processed with rest measure completion, compatible with CLaMP 2. Each of these subdirectories will contain a model-specific folder, named as a combination of the model's name and its sampling parameters.
186
+
187
+ #### 2. Extract Generated Data Features
188
+
189
+ Modify ```input_dir``` and ```output_dir``` in ```clamp2/extract_clamp2.py```:
190
+ ```python
191
+ input_dir = '../output/interleaved/weights_notagen_schubert_p_size_16_p_length_1024_p_layers_20_c_layers_6_h_size_1280_lr_1e-05_batch_1_k_9_p_0.9_temp_1.2' # interleaved abc folder
192
+ output_dir = 'feature/weights_notagen_schubert_p_size_16_p_length_1024_p_layers_20_c_layers_6_h_size_1280_lr_1e-05_batch_1_k_9_p_0.9_temp_1.2' # feature folder
193
+ ```
194
+ Extract the features:
195
+ ```
196
+ cd clamp2/
197
+ python extract_clamp2.py
198
+ ```
199
+
200
+ #### 3. Statistics on Averge CLaMP 2 Score (Optional)
201
+ If you're interested in the **Average CLaMP 2 Score** of the current model, modify the parameters in ```clamp2/statistics.py```:
202
+ ```python
203
+ gt_feature_folder = 'feature/schubert_interleaved'
204
+ output_feature_folder = 'feature/weights_notagen_schubert_p_size_16_p_length_1024_p_layers_20_c_layers_6_h_size_1280_lr_1e-05_batch_1_k_9_p_0.9_temp_1.2'
205
+ ```
206
+ Then run this script:
207
+ ```
208
+ cd clamp2/
209
+ python statistics.py
210
+ ```
211
+
212
+ #### 4. Construct Preference Data
213
+ Modify the parameters in ```RL/data.py```:
214
+ ```python
215
+ gt_feature_folder = '../clamp2/feature/schubert_interleaved'
216
+ output_feature_folder = '../clamp2/feature/weights_notagen_schubert_p_size_16_p_length_1024_p_layers_20_c_layers_6_h_size_1280_lr_1e-05_batch_1_k_9_p_0.9_temp_1.2'
217
+ output_original_abc_folder = '../output/original/weights_notagen_schubert_p_size_16_p_length_1024_p_layers_20_c_layers_6_h_size_1280_lr_1e-05_batch_1_k_9_p_0.9_temp_1.2'
218
+ output_interleaved_abc_folder = '../output/interleaved/weights_notagen_schubert_p_size_16_p_length_1024_p_layers_20_c_layers_6_h_size_1280_lr_1e-05_batch_1_k_9_p_0.9_temp_1.2'
219
+ data_index_path = 'schubert_RL1.json' # Data for the first iteration of RL
220
+ data_select_portion = 0.1
221
+ ```
222
+ In this script, the **CLaMP 2 Score** of each generated piece will be calculated and sorted. The portion of data in the chosen and rejected sets is determined by ```data_select_portion```. Additionally, there are also three rules to exclude problematic sheets from the chosen set:
223
+ - Sheets with duration alignment problems are excluded;
224
+ - Sheets that may plagiarize from ground truth data (ld_sim>0.95) are excluded;
225
+ - Sheets where staves for the same instrument are not grouped together are excluded.
226
+
227
+ The prefence data file will be names as ```data_index_path```, which records the file paths in chosen and rejected sets.
228
+
229
+ Run this script:
230
+ ```
231
+ cd RL/
232
+ python data.py
233
+ ```
234
+
235
+ #### 5. DPO Training
236
+
237
+ Modify the parameters in ```RL/config.py```:
238
+ ```python
239
+ DATA_INDEX_PATH = 'schubert_RL1.json' # Preference data path
240
+ PRETRAINED_PATH = '../finetune/weights_notagen_schubert_p_size_16_p_length_1024_p_layers_20_c_layers_6_h_size_1280_lr_1e-05_batch_1.pth' # The model to go through DPO optimization
241
+ EXP_TAG = 'schubert-RL1' # Model tag for differentiation
242
+ ```
243
+ You can also modify other parameters like ```OPTIMATION_STEPS``` and DPO hyper-parameters.
244
+
245
+ Run this script:
246
+ ```
247
+ cd RL/
248
+ CUDA_VISIBLE_DEVICES=0 python train.py
249
+ ```
250
+ After training, a model named ```weights_notagen_schubert-RL1_beta_0.1_lambda_10_p_size_16_p_length_1024_p_layers_20_c_layers_6_h_size_1280_lr_1e-06_batch_1.pth``` will be saved under ```RL/```. For the second round of CLaMP-DPO, please go back to the first inference stage, and let the new model to generate pieces.
251
+
252
+ For this small experiment on **Schubert's lieder** data, we post our **Average CLaMP 2 Score** here for the fine-tuned model and models after each iteration of CLaMP-DPO, as a reference:
253
+
254
+ | CLaMP-DPO Iteration (K) | Average CLaMP 2 Score |
255
+ | ---- | ---- |
256
+ | 0 (fine-tuned) | 0.324 |
257
+ | 1 | 0.579 |
258
+ | 2 | 0.778 |
259
+
260
+ If you are interested in this method, have a try on your own style-specific dataset :D
261
 
262
  ## πŸ“š Citation
263
 
 
275
  }
276
  ```
277
 
278
+ ## πŸ”— Links
279
+ - [CLaMP 2 Paper](https://arxiv.org/pdf/2410.13267)
280
+ - [CLaMP 2 Code](https://github.com/sanderwood/clamp2)