Instructions to use KoshiMazaki/akuspace-ltx25 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- LTX.io
How to use KoshiMazaki/akuspace-ltx25 with LTX.io:
# Install the LTX-2 pipelines git clone https://github.com/Lightricks/LTX-2.git cd LTX-2 uv sync --frozen
# Download the weights from this repo, plus the Gemma text encoder hf download KoshiMazaki/akuspace-ltx25 --local-dir models/akuspace-ltx25 hf download google/gemma-3-12b-it-qat-q4_0-unquantized --local-dir models/gemma-3-12b
# Text/image-to-video with the LoRA on the HQ two-stage base pipeline uv run python -m ltx_pipelines.ti2vid_two_stages_hq \ --checkpoint-path path/to/checkpoint.safetensors \ --distilled-lora path/to/distilled_lora.safetensors 0.8 \ --spatial-upsampler-path path/to/spatial_upsampler.safetensors \ --gemma-root models/gemma-3-12b \ --lora models/akuspace-ltx25/<weights>.safetensors 1.0 \ --prompt "your prompt here" \ --output-path output.mp4 # For image-to-video, add: --image path/to/image.jpg 0 0.8 - Reverb
How to use KoshiMazaki/akuspace-ltx25 with Reverb:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
scripts/dataset: add build_v5_rooms.py
Browse files
scripts/dataset/build_v5_rooms.py
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Build cathedral and small room at three levels, normalised to the joint batch.
|
| 2 |
+
|
| 3 |
+
Three render batches exist, made in separate sessions at different send settings,
|
| 4 |
+
so the same level word currently means different amounts depending on which batch
|
| 5 |
+
a source came from:
|
| 6 |
+
|
| 7 |
+
cathedral high small high
|
| 8 |
+
joint (8) -19.7 -14.3
|
| 9 |
+
male-female (4) -18.9 -7.7
|
| 10 |
+
claps, old (2) -9.1 -7.4
|
| 11 |
+
|
| 12 |
+
Cathedral: joint and male-female already agree to 0.8 dB; the claps sit 10 dB
|
| 13 |
+
wetter. Small room: male-female and claps agree; the joint batch is 6.6 dB drier.
|
| 14 |
+
Each space has one batch out of step, and a different one each time.
|
| 15 |
+
|
| 16 |
+
TARGET IS THE JOINT BATCH, per Radek. Every source is scaled to the joint median
|
| 17 |
+
for its space and level, so a level word means one measured amount everywhere.
|
| 18 |
+
|
| 19 |
+
BEATS ARE EXCLUDED, as previously decided: they needed the largest corrections and
|
| 20 |
+
they are percussive, where a dense reverb reads very differently from how it reads
|
| 21 |
+
on sustained material.
|
| 22 |
+
|
| 23 |
+
Claps have only ONE rendered level (the old batch). Since they are verified send
|
| 24 |
+
mixes, low and mid are derived offline by scaling R — the method validated at
|
| 25 |
+
-71.6 dB against a real Ableton render, i.e. inaudible.
|
| 26 |
+
|
| 27 |
+
Scaling touches R only, never the dry, so the dry stays a true dry.
|
| 28 |
+
"""
|
| 29 |
+
import subprocess
|
| 30 |
+
import wave
|
| 31 |
+
import os
|
| 32 |
+
from pathlib import Path
|
| 33 |
+
|
| 34 |
+
import numpy as np
|
| 35 |
+
|
| 36 |
+
SR, SLOT = 48000, 6 * 48000
|
| 37 |
+
BASE = Path(os.environ.get("AKUSPACE_DATASET", "../../../../AUDIO-LTX-LORA/Dataset"))
|
| 38 |
+
JOINT, MF, SLICED = BASE / "Levels-Reverb/joint-catedral", BASE / "male-female", BASE / "Sliced"
|
| 39 |
+
OUT = BASE / "v5-rooms"
|
| 40 |
+
|
| 41 |
+
JOINT_SRC = ["citola_01", "citola_02", "beat_01", "beat_02",
|
| 42 |
+
"male_voice_01", "male_voice_02", "piano_01", "piano_sax"]
|
| 43 |
+
MF_SRC = ["female_new_01", "female_new_02", "male_new_01", "male_new_02"]
|
| 44 |
+
LEVELS = ["low", "mid", "high"]
|
| 45 |
+
NO_NORMALIZE = {"beat_01", "beat_02"}
|
| 46 |
+
CEILING_DB = -3.0
|
| 47 |
+
|
| 48 |
+
SPACES = {
|
| 49 |
+
"synthetic_cathedral": {
|
| 50 |
+
"joint": ("dry.wav", ["cathedral low.wav", "cathedral mid.wav", "cathedral high.wav"]),
|
| 51 |
+
"mf": ("female-male-dry.wav", ["female-male-cathedral-low.wav",
|
| 52 |
+
"female-male-cathedral-mid.wav", "female-male-cathedral.wav"]),
|
| 53 |
+
"claps_dir": "synthetic_cathedral",
|
| 54 |
+
},
|
| 55 |
+
"small_room_0_67": {
|
| 56 |
+
"joint": ("dry.wav", ["smallroom_low.wav", "smallroom_mid.wav", "smallroom_high.wav"]),
|
| 57 |
+
"mf": ("female-male-dry.wav", ["female-male-small-low.wav",
|
| 58 |
+
"female-male-small-mid.wav", "female-male-small.wav"]),
|
| 59 |
+
"claps_dir": "small_room_0_67",
|
| 60 |
+
},
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
|
| 64 |
+
def load(p, ch=2):
|
| 65 |
+
r = subprocess.run(["ffmpeg", "-v", "error", "-i", str(p), "-ac", str(ch),
|
| 66 |
+
"-ar", str(SR), "-f", "f32le", "-"], capture_output=True)
|
| 67 |
+
return np.frombuffer(r.stdout, dtype="<f4").astype(np.float64).reshape(-1, ch)
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
def save(x, p):
|
| 71 |
+
p.parent.mkdir(parents=True, exist_ok=True)
|
| 72 |
+
y = np.clip(x, -1.0, 1.0)
|
| 73 |
+
i = (y * 8388607.0).astype(np.int32)
|
| 74 |
+
b = np.stack([i & 0xFF, (i >> 8) & 0xFF, (i >> 16) & 0xFF], axis=-1).astype(np.uint8)
|
| 75 |
+
with wave.open(str(p), "wb") as w:
|
| 76 |
+
w.setnchannels(x.shape[1]); w.setsampwidth(3); w.setframerate(SR)
|
| 77 |
+
w.writeframes(b.tobytes())
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
def db(x):
|
| 81 |
+
return 20 * np.log10(np.sqrt((x ** 2).mean()) + 1e-12)
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
def ratio(d, R):
|
| 85 |
+
return db(R.mean(axis=1)) - db(d.mean(axis=1))
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
# ---- gather every (source, space, level) as dry + R ------------------------
|
| 89 |
+
pairs = {}
|
| 90 |
+
for space, cfg in SPACES.items():
|
| 91 |
+
dj = load(JOINT / cfg["joint"][0])
|
| 92 |
+
wj = [load(JOINT / f) for f in cfg["joint"][1]]
|
| 93 |
+
for i, src in enumerate(JOINT_SRC):
|
| 94 |
+
a, b = i * SLOT, (i + 1) * SLOT
|
| 95 |
+
d = dj[a:b]
|
| 96 |
+
for lv, w in zip(LEVELS, wj):
|
| 97 |
+
pairs[(src, space, lv)] = ("joint", d, w[a:b] - d)
|
| 98 |
+
|
| 99 |
+
dm = load(MF / cfg["mf"][0])
|
| 100 |
+
wm = [load(MF / f) for f in cfg["mf"][1]]
|
| 101 |
+
for i, src in enumerate(MF_SRC):
|
| 102 |
+
a, b = i * SLOT, (i + 1) * SLOT
|
| 103 |
+
d = dm[a:b]
|
| 104 |
+
for lv, w in zip(LEVELS, wm):
|
| 105 |
+
pairs[(src, space, lv)] = ("male-female", d, w[a:b] - d)
|
| 106 |
+
|
| 107 |
+
# claps: one rendered level, treated as "high"; low/mid derived after scaling
|
| 108 |
+
for src in ("claps_rhythm", "claps_single"):
|
| 109 |
+
dp, wp = SLICED / "dry" / f"{src}.wav", SLICED / cfg["claps_dir"] / f"{src}.wav"
|
| 110 |
+
if dp.exists() and wp.exists():
|
| 111 |
+
d, w = load(dp)[:SLOT], load(wp)[:SLOT]
|
| 112 |
+
n = min(len(d), len(w))
|
| 113 |
+
pairs[(src, space, "high")] = ("claps", d[:n], w[:n] - d[:n])
|
| 114 |
+
|
| 115 |
+
# ---- joint medians are the target ------------------------------------------
|
| 116 |
+
targets = {}
|
| 117 |
+
for space in SPACES:
|
| 118 |
+
for lv in LEVELS:
|
| 119 |
+
vals = [ratio(d, R) for (s, sp, l), (b, d, R) in pairs.items()
|
| 120 |
+
if sp == space and l == lv and b == "joint"]
|
| 121 |
+
targets[(space, lv)] = float(np.median(vals))
|
| 122 |
+
print("targets (joint medians):")
|
| 123 |
+
for (space, lv), t in sorted(targets.items()):
|
| 124 |
+
print(f" {space:<22} {lv:<5} {t:>+7.1f} dB")
|
| 125 |
+
|
| 126 |
+
# ---- normalise, derive missing clap levels, write ---------------------------
|
| 127 |
+
print(f"\n{'source':<16} {'space':<22} {'level':<5} {'was':>8} {'corr':>7} {'now':>8}")
|
| 128 |
+
print("-" * 74)
|
| 129 |
+
out, corrections = {}, []
|
| 130 |
+
for space in SPACES:
|
| 131 |
+
for src in JOINT_SRC + MF_SRC + ["claps_rhythm", "claps_single"]:
|
| 132 |
+
base = pairs.get((src, space, "high"))
|
| 133 |
+
if base is None:
|
| 134 |
+
continue
|
| 135 |
+
batch, d, R_high = base
|
| 136 |
+
for lv in LEVELS:
|
| 137 |
+
key = (src, space, lv)
|
| 138 |
+
if key in pairs:
|
| 139 |
+
_, d, R = pairs[key]
|
| 140 |
+
else:
|
| 141 |
+
# derive from high by the ratio the joint targets imply
|
| 142 |
+
R = R_high * 10 ** ((targets[(space, lv)] - targets[(space, "high")]) / 20)
|
| 143 |
+
was = ratio(d, R)
|
| 144 |
+
if src in NO_NORMALIZE:
|
| 145 |
+
corr = 0.0
|
| 146 |
+
else:
|
| 147 |
+
corr = targets[(space, lv)] - was
|
| 148 |
+
R = R * 10 ** (corr / 20)
|
| 149 |
+
out[key] = (d, R)
|
| 150 |
+
if abs(corr) > 0.05:
|
| 151 |
+
corrections.append(abs(corr))
|
| 152 |
+
print(f"{src:<16} {space:<22} {lv:<5} {was:>+7.1f} {corr:>+6.1f} "
|
| 153 |
+
f"{ratio(d, R):>+7.1f}" + (" (beats: left as rendered)" if src in NO_NORMALIZE else ""))
|
| 154 |
+
|
| 155 |
+
# uniform trim so nothing clips; changes no ratio anywhere
|
| 156 |
+
peak = max(20 * np.log10(np.abs(d + R).max() + 1e-12) for d, R in out.values())
|
| 157 |
+
trim = min(0.0, CEILING_DB - peak)
|
| 158 |
+
print(f"\nloudest {peak:+.1f} dBFS -> uniform trim {trim:+.1f} dB (ceiling {CEILING_DB:+g})")
|
| 159 |
+
|
| 160 |
+
for (src, space, lv), (d, R) in out.items():
|
| 161 |
+
g = 10 ** (trim / 20)
|
| 162 |
+
save((d + R) * g, OUT / space / lv / f"{src}.wav")
|
| 163 |
+
save(d * g, OUT / space / "dry" / f"{src}.wav")
|
| 164 |
+
|
| 165 |
+
n = len(out)
|
| 166 |
+
print(f"\n{n} pairs -> {OUT}")
|
| 167 |
+
print(f" {len(set(k[0] for k in out))} sources x {len(SPACES)} spaces x {len(LEVELS)} levels")
|
| 168 |
+
print(f" corrections applied: {len(corrections)}, median {np.median(corrections):.1f} dB, "
|
| 169 |
+
f"max {max(corrections):.1f} dB")
|