| from collections import deque |
| from pathlib import Path |
|
|
| import gradio as gr |
| import numpy as np |
| import onnxruntime as ort |
|
|
|
|
| ROOT = Path(__file__).parent |
| MODEL_PATH = ROOT / "model_int8.onnx" |
| VOCAB_PATH = ROOT / "vocab.json" |
| TEMPERATURE = 0.9 |
| TOP_K = 32 |
| TOKENS_PER_UPDATE = 24 |
|
|
|
|
| def load_vocab(): |
| import json |
|
|
| vocab = json.loads(VOCAB_PATH.read_text(encoding="utf-8")) |
| return vocab["stoi"], {int(key): value for key, value in vocab["itos"].items()} |
|
|
|
|
| session = ort.InferenceSession(str(MODEL_PATH), providers=["CPUExecutionProvider"]) |
| stoi, itos = load_vocab() |
| h_shape = session.get_inputs()[1].shape |
| num_layers = int(h_shape[0]) |
| hidden_size = int(h_shape[2]) |
|
|
|
|
| def sample(logits, rng): |
| scores = np.asarray(logits, dtype=np.float64).reshape(-1) / TEMPERATURE |
| eos_id = stoi.get("EOS") |
| if eos_id is not None: |
| scores[eos_id] -= 1.0 |
| k = min(TOP_K, scores.size) |
| ids = np.argpartition(scores, -k)[-k:] |
| values = scores[ids] |
| probabilities = np.exp(values - values.max()) |
| probabilities /= probabilities.sum() |
| return int(rng.choice(ids, p=probabilities)) |
|
|
|
|
| def step(token_id, h, c, rng): |
| outputs = session.run( |
| ["logits", "h_out", "c_out"], |
| { |
| "input": np.array([[token_id]], dtype=np.int64), |
| "h": h, |
| "c": c, |
| }, |
| ) |
| return sample(outputs[0], rng), outputs[1], outputs[2] |
|
|
|
|
| def generate(): |
| rng = np.random.default_rng() |
| h = np.zeros((num_layers, 1, hidden_size), dtype=np.float32) |
| c = np.zeros_like(h) |
| prompt = ["BOS", "BPM_120", "GRID_64", "BAR", "POS_0"] |
| prompt_ids = [stoi[token] for token in prompt if token in stoi] |
| current_id = prompt_ids[0] if prompt_ids else 0 |
|
|
| for token_id in prompt_ids[1:]: |
| _, h, c = step(current_id, h, c, rng) |
| current_id = token_id |
|
|
| history = deque((itos[token_id] for token_id in prompt_ids), maxlen=600) |
| while True: |
| for _ in range(TOKENS_PER_UPDATE): |
| current_id, h, c = step(current_id, h, c, rng) |
| history.append(itos.get(current_id, "<?>")) |
| yield " ".join(history) |
|
|
|
|
| with gr.Blocks(title="NanoMaestro CPU Demo") as demo: |
| gr.Markdown( |
| "**For faster, fully local inference, try the " |
| "[Transformers.js browser demo](https://huggingface.co/spaces/utkucoban/NanoMaestro-Realtime).**" |
| ) |
| gr.Markdown("# NanoMaestro CPU Symbolic Generator") |
| output = gr.Textbox(label="Continuous symbolic events", lines=18, max_lines=18) |
| with gr.Row(): |
| start = gr.Button("Start", variant="primary") |
| stop = gr.Button("Stop") |
|
|
| generation = start.click(generate, outputs=output) |
| stop.click(fn=None, cancels=[generation]) |
|
|
|
|
| if __name__ == "__main__": |
| demo.queue(default_concurrency_limit=1).launch() |
|
|