Downloads · 30 days
0
Eikovo/SeaOtter-0.5-Beta
SeaOtter-0.5-Beta is a text-to-audio model from Eikovo. Use it for the text-to-audio task on the model card, and read the license before you ship it in a product. The card lists the license as apache-2.0.
This is an early test checkpoint for generating piano music in MIDI format from natural language prompts. It takes text prompts describing tempo, mood, and key, then generates symbolic REMI tokens that convert into st…
Downloads · 30 days
0
Access
Public
Updated Aug 28, 2026
Repo size
5.4 GB
Likes
1
Public
Click a slice to open those files.
Other2.1 GB · 36%
From the Hugging Face model README
This is an early test checkpoint for generating piano music in MIDI format from natural language prompts. It takes text prompts describing tempo, mood, and key, then generates symbolic REMI tokens that convert into standard .mid files.
How It Was Trained
unsloth/Qwen2.5-3B-Instruct-bnb-4bitq, k, v, o, gate, up, down)SFTTrainerCurrent State & Limitations (v0.1 Beta)
miditok_config.json.What Is Coming Next (v1.1 Plan)
use_chords=True so the model outputs full chords as single dedicated tokens.How to Run Inference
import os
import torch
from unsloth import FastLanguageModel
from miditok import REMI
from miditok.classes import TokSequence
from symusic import Score
model_path = "eikovo/piano-midi-beta"
config_path = "miditok_config.json"
midi_tokenizer = REMI(params=config_path)
model, tokenizer = FastLanguageModel.from_pretrained(
model_name=model_path,
max_seq_length=2048,
load_in_4bit=True,
)
FastLanguageModel.for_inference(model)
prompt = "A soft, expressive piano piece in A minor at 80 BPM."
messages = [
{"role": "user", "content": f"Generate piano MIDI tokens matching this description: {prompt}"}
]
inputs = tokenizer.apply_chat_template(
messages,
tokenize=True,
add_generation_prompt=True,
return_tensors="pt"
).to("cuda")
with torch.inference_mode():
outputs = model.generate(
input_ids=inputs,
max_new_tokens=1400,
min_new_tokens=128,
temperature=0.92,
top_k=40,
top_p=0.90,
repetition_penalty=1.15,
do_sample=True,
use_cache=True,
pad_token_id=tokenizer.eos_token_id
)
raw_output = tokenizer.decode(outputs[0][inputs.shape[1]:], skip_special_tokens=True)
raw_tokens = [t.strip() for t in raw_output.split() if t.strip()]
valid_tokens = [t for t in raw_tokens if t in midi_tokenizer.vocab]
if not valid_tokens[0].startswith("Bar_") and not valid_tokens[0].startswith("Position_"):
valid_tokens = ["Bar_None", "Position_0"] + valid_tokens
seq = TokSequence(tokens=valid_tokens)
midi_tokenizer.complete_sequence(seq)
score = midi_tokenizer.decode([seq])
score = score.resample(480)
score.dump_midi("output.mid")
Credits Eikovo for the: training, programming, testing, refining Discord: Eikovo