Skip to content

Commit

Permalink
Improve pylint score, readme, and actions
Browse files Browse the repository at this point in the history
  • Loading branch information
pranitsh committed Sep 28, 2023
1 parent c7c6f7a commit aaf5bbf
Show file tree
Hide file tree
Showing 19 changed files with 196 additions and 285 deletions.
16 changes: 14 additions & 2 deletions .github/workflows/pylint.yml → .github/workflows/py.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Pylint
name: Pylint, Pytest, and PyPI

on: [push]

Expand All @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10"]
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
Expand All @@ -17,11 +17,23 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pylint
- name: Analysing the code with pylint
run: |
pylint $(git ls-files '*.py')
continue-on-error: true
- name: actions-pytest
uses: xoviat/actions-pytest@0.1-alpha2
with:
args: ./tuneease
continue-on-error: true
- name: Try pip installation
run: |
pip install -e .
continue-on-error: true
- name: Memory_Profiler
run: |
pip install memory_profiler
python -m memory_profiler ./tuneease/tests/memory.py
continue-on-error: true
39 changes: 18 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Welcome to Tune Ease! This project provides intuitive website control and automa
**Do not run this without a virtual environment!**
1. Create a virtual environment using Python 3:
```sh
python3 -m venv venv
python3 -m venv env
```
2. Activate the virtual environment:
- On macOS/Linux: `source venv/bin/activate`
Expand Down Expand Up @@ -72,31 +72,28 @@ Feel free to choose the setup option that best suits your needs. Enjoy the proje
1. Introduced the ability to use a CPU or a GPU.
2. Structural changes to the structure.
1. Instead of using a yaml to instantiate the model, I used a new train.py with a variable that contains the data from train.yaml
2. Created a folder named pipeline that contains code that was previously duplicated many times. (Quite painful...)
3. Improved the Pylint score from 1.25 to 2.46
2. Created a folder named pipeline that contains code that was previously duplicated many times.
3. Prevented duplicated runs of the same code with new classes
4. Improved the Pylint score from 1.25 to 3.90
3. Changed hierarchy and propagated changes.
4. Packaged this into a code shareable repo. This mean the install time has been reduced from the initial 4-5 hours it took me in the beginning to an automatic install process offered here.
4. Packaged this into a code shareable repo. This mean the install time has been reduced from the initial 4-5 hours it took me in the beginning to the more automatic install process offered here.

# Usage

If you cloned the repo:
```sh
python -m tuneease.tuneease # generates a file and prints the location to the file
python -m tuneease.server # starts the server for you to use the app through the port that is printed
```
If you installed through pip:
```sh
tuneease-generate # generates something and prints the location of the generated file
tuneease # starts the server and prints the port to go to for the website
Attempts are made to find your MuseScore and checkpoint path automatically. **Optionally, include your MuseScore and checkpoint path with the flag.** You do not need MuseScore most of the time, but you will need the checkpoint for the AI music.

Use the below to generate one file.
```bash
# If you installed through pip
tuneease-generate --checkpoint_path <required path>
# If you installed through code sharing
python -m tuneease.tuneease --checkpoint_path <required path>
```
Attempts are made to find your MuseScore and checkpoint path automatically. **Optionally, include your MuseScore and checkpoint path with the flag**
```sh
# For just generating one item
tuneease-generate --museScore_path <path> --checkpoint_path <path>
python -m tuneease.tuneease --museScore_path <path> --checkpoint_path <path>
# For the server
tuneease --museScore_path <path> --checkpoint_path <path>
python -m tuneease.server --museScore_path <path> --checkpoint_path <path>

If you want to use the server, the website is mainly for using the AI.
```bash
tuneease --museScore_path <optional path> --checkpoint_path <optional path>
python -m tuneease.server --museScore_path <optional path> --checkpoint_path <optional path>
```
Normally, you can access the server at http://localhost:8080, or you can follow whatever port flask tells you to go to.

Expand Down
6 changes: 3 additions & 3 deletions tuneease/getmusic/data/bigdata.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from torch.utils.data import Dataset
import numpy as np
import torch
import random
import itertools as it
from ...getmusic.data.indexed_datasets import IndexedDataset
import numpy as np
import torch
from torch.utils.data import Dataset

class BigDataset(Dataset):
def __init__(self, prefix, vocab_size, path=None):
Expand Down
2 changes: 1 addition & 1 deletion tuneease/getmusic/distributed/launch.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import torch
from torch import distributed as dist
from torch import multiprocessing as mp
import distributed as dist_fn
from . import distributed as dist_fn

def find_free_port():
import socket
Expand Down
12 changes: 6 additions & 6 deletions tuneease/getmusic/engine/solver.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ def __init__(self, gpu, config, args, model, dataloader, logger, is_sample=False

self.logger.debug('Load dictionary: {} tokens.'.format(len(self.t_h.ids_to_tokens)))

beat_note_factor =mc.beat_note_factor
max_notes_per_bar = mc.max_notes_per_bar
pos_resolution = mc.pos_resolution
bar_max = mc.bar_max
beat_note_factor =mc.BEAT_NOTE_FACTOR
max_notes_per_bar = mc.MAX_NOTES_PER_BAR
pos_resolution = mc.POS_RESOLUTION
bar_max = mc.BAR_MAX
self.pos_in_bar = beat_note_factor * max_notes_per_bar * pos_resolution
self.pad_index = mc.duration_max * mc.pos_resolution - 1
self.figure_size = mc.bar_max * mc.beat_note_factor * mc.max_notes_per_bar * mc.pos_resolution
self.pad_index = mc.DURATION_MAX * mc.POS_RESOLUTION - 1
self.figure_size = mc.BAR_MAX * mc.BEAT_NOTE_FACTOR * mc.MAX_NOTES_PER_BAR * mc.POS_RESOLUTION

if 'clip_grad_norm' in config['solver']:
self.clip_grad_norm = instantiate_from_config(config['solver']['clip_grad_norm'])
Expand Down
8 changes: 4 additions & 4 deletions tuneease/getmusic/modeling/roformer/diffusion_roformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ def __init__(
self.num_classes = self.roformer.vocab_size + 1 # defined in vocabulary, add an additional mask
self.cond_weight = self.roformer.cond_weight
self.tracks = 14
self.pad_index = mc.duration_max * mc.pos_resolution - 1
self.figure_size = mc.bar_max * mc.beat_note_factor * mc.max_notes_per_bar * mc.pos_resolution
self.pad_index = mc.DURATION_MAX * mc.POS_RESOLUTION - 1
self.figure_size = mc.BAR_MAX * mc.BEAT_NOTE_FACTOR * mc.MAX_NOTES_PER_BAR * mc.POS_RESOLUTION
self.num_timesteps = diffusion_step
self.parametrization = 'x0'
self.auxiliary_loss_weight = auxiliary_loss_weight
Expand Down Expand Up @@ -174,8 +174,8 @@ def log_sample_categorical_infer(self, logits, figure_size): # use gum
if i % 2 == 1: # duration
track[:, self.pad_index+1:-1, :] = -70 # only decode duration tokens
else: # only decode pitch tokens in $i$-th track
start = mc.tracks_start[i // 2]
end = mc.tracks_end[i // 2]
start = mc.TRACKS_START[i // 2]
end = mc.TRACKS_END[i // 2]
track[:,:self.pad_index, :] = -70
track[:,self.pad_index+1:start,:] = -70
track[:,end+1:-1,:] = -70
Expand Down
46 changes: 23 additions & 23 deletions tuneease/getmusic/utils/midi_config.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
pos_resolution = 4 # 16 # per beat (quarter note)
bar_max = 32
velocity_quant = 4
tempo_quant = 12 # 2 ** (1 / 12)
min_tempo = 16
max_tempo = 256
duration_max = 4 # 2 ** 8 * beat
max_ts_denominator = 6 # x/1 x/2 x/4 ... x/64
max_notes_per_bar = 1 # 1/64 ... 128/64 #
beat_note_factor = 4 # In MIDI format a note is always 4 beats
deduplicate = True
filter_symbolic = False
filter_symbolic_ppl = 16
trunc_pos = 2 ** 16 # approx 30 minutes (1024 measures)
sample_len_max = 1024 # window length max
sample_overlap_rate = 1.5
ts_filter = True
pool_num = 200
max_inst = 127
max_pitch = 127
max_velocity = 127
tracks_start = [16, 144, 997, 5366, 6921, 10489]
tracks_end = [143, 996, 5365, 6920, 10488, 11858]
POS_RESOLUTION = 4 # 16 # per beat (quarter note)
BAR_MAX = 32
VELOCITY_QUANT = 4
TEMPO_QUANT = 12 # 2 ** (1 / 12)
MIN_TEMPO = 16
MAX_TEMPO = 256
DURATION_MAX = 4 # 2 ** 8 * beat
MAX_TS_DENOMINATOR = 6 # x/1 x/2 x/4 ... x/64
MAX_NOTES_PER_BAR = 1 # 1/64 ... 128/64 #
BEAT_NOTE_FACTOR = 4 # In MIDI format a note is always 4 beats
DEDUPLICATE = True
FILTER_SYMBOLIC = False
FILTER_SYMBOLIC_PPL = 16
TRUNC_POS = 2 ** 16 # approx 30 minutes (1024 measures)
SAMPLE_LEN_MAX = 1024 # window length max
SAMPLE_OVERLAP_RATE = 1.5
TS_FILTER = True
POOL_NUM = 200
MAX_INST = 127
MAX_PITCH = 127
MAX_VELOCITY = 127
TRACKS_START = [16, 144, 997, 5366, 6921, 10489]
TRACKS_END = [143, 996, 5365, 6920, 10488, 11858]
4 changes: 2 additions & 2 deletions tuneease/getmusic/utils/misc.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import importlib
import random
import numpy as np
import torch
import warnings
import os
import numpy as np
import torch

def seed_everything(seed, cudnn_deterministic=False):
"""
Expand Down
8 changes: 3 additions & 5 deletions tuneease/pathutility.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,18 +163,16 @@ def musescore_path(self, printsuccess = False):
return filename
self.logger.info("On Windows and macOS, install MuseScore through the website:")
self.logger.info("[https://musescore.org/en](https://musescore.org/en).")
self.logger.info("Attempts are made to find it automatically. Tested for windows.")
self.logger.info("If necessary, use --museScore_path <museScore_path>")
self.logger.info("Attempts are made to find it automatically. If necessary, use --musescore_path <path>")
return None

def checkpoint_path(self, printsuccess = False):
path = os.path.join(self.project_directory(), "checkpoint.pth")
if not os.path.exists(path):
self.logger.info("You have to install the below with the following path:")
self.logger.info("Install the below at the following path or use --checkpoint_path <path>")
fileurl = 'https://1drv.ms/u/s!ArHNvccy1VzPkWGKXZDQY5k-kDi4?e=fFxcEq'
self.logger.info(fileurl)
toprint = fileurl + f"{path}"
self.logger.info(toprint)
self.logger.info(path)
return None
else:
if printsuccess:
Expand Down
Loading

0 comments on commit aaf5bbf

Please sign in to comment.