Initial release

This commit is contained in:
civ
2026-08-16 18:24:52 +07:00
commit 876886a39a
13244 changed files with 2353959 additions and 0 deletions
+37
View File
@@ -0,0 +1,37 @@
#!/bin/bash
# Roundtrip: audio -> understand -> SFT DiT -> MP3
#
# Usage: ./ace-understand.sh input.wav (or input.mp3)
#
# understand:
# input -> ace-understand.json (audio codes + metadata)
#
# ace-synth:
# ace-understand.json -> ace-understand0.mp3
set -eu
if [ $# -lt 1 ]; then
echo "Usage: $0 <input.wav|input.mp3>"
exit 1
fi
input="$1"
../build/ace-understand \
--src-audio "$input" \
--dit ../models/acestep-v15-sft-Q8_0.gguf \
--vae ../models/vae-BF16.gguf \
--lm ../models/acestep-5Hz-lm-4B-Q8_0.gguf \
-o ace-understand.json
sed -i \
's/"audio_cover_strength": *[0-9.]*/"audio_cover_strength": 0.04/' \
ace-understand.json
../build/ace-synth \
--src-audio "$input" \
--request ace-understand.json \
--embedding ../models/Qwen3-Embedding-0.6B-Q8_0.gguf \
--dit ../models/acestep-v15-sft-Q8_0.gguf \
--vae ../models/vae-BF16.gguf
+104
View File
@@ -0,0 +1,104 @@
#!/usr/bin/env python3
# client-batch.py: test batching via ace-server
#
# POST /lm (lm_batch_size=2 in JSON) -> 2 enriched requests
# POST /synth (JSON array of 2 requests) -> 2 MP3s in one GPU batch
#
# Start the server first: ./server.sh
import json
import sys
import urllib.error
import urllib.request
URL = "http://127.0.0.1:8085"
def post_json(endpoint, data):
body = json.dumps(data).encode()
req = urllib.request.Request(
URL + endpoint,
data=body,
headers={"Content-Type": "application/json"},
)
with urllib.request.urlopen(req) as resp:
return resp.read(), resp.headers
def parse_multipart_mixed(data, content_type):
"""Parse multipart/mixed response into list of body bytes."""
boundary = None
for part in content_type.split(";"):
part = part.strip()
if part.startswith("boundary="):
boundary = part[len("boundary="):].strip().encode()
break
if not boundary:
raise ValueError("no boundary in content-type: " + content_type)
delimiter = b"--" + boundary
parts = []
for chunk in data.split(delimiter):
if not chunk or chunk.startswith(b"--"):
continue
chunk = chunk.strip(b"\r\n")
if not chunk:
continue
sep = chunk.find(b"\r\n\r\n")
if sep < 0:
continue
body = chunk[sep + 4:]
if body.endswith(b"\r\n"):
body = body[:-2]
parts.append(body)
return parts
# Phase 1: LM generates N variations
try:
with open("simple-batch.json") as f:
request_json = json.load(f)
except FileNotFoundError:
print("ERROR: simple-batch.json not found (run from the examples/ directory)")
sys.exit(1)
try:
lm_batch_size = request_json.get("lm_batch_size", 1)
print("POST /lm (lm_batch_size=%d)..." % lm_batch_size)
lm_data, _ = post_json("/lm", request_json)
except urllib.error.URLError as e:
print("ERROR: cannot connect to %s (%s)" % (URL, e.reason))
print("Start the server first: ./server.sh")
sys.exit(1)
lm_results = json.loads(lm_data)
print(" -> %d enriched requests" % len(lm_results))
# Phase 2: synth all in one GPU batch (send JSON array)
print("POST /synth (batch=%d, JSON array)..." % len(lm_results))
body = json.dumps(lm_results).encode()
req = urllib.request.Request(
URL + "/synth",
data=body,
headers={"Content-Type": "application/json"},
)
with urllib.request.urlopen(req) as resp:
resp_data = resp.read()
content_type = resp.headers.get("Content-Type", "")
if "multipart/mixed" in content_type:
parts = parse_multipart_mixed(resp_data, content_type)
for i, mp3_data in enumerate(parts):
path = "server-batch%d.mp3" % i
with open(path, "wb") as f:
f.write(mp3_data)
print(" -> %s (%d bytes)" % (path, len(mp3_data)))
else:
path = "server-batch0.mp3"
with open(path, "wb") as f:
f.write(resp_data)
print(" -> %s (%d bytes)" % (path, len(resp_data)))
print("Done: %d MP3(s)" % len(lm_results))
+54
View File
@@ -0,0 +1,54 @@
#!/bin/bash
# Roundtrip via ace-server: audio -> understand -> synth -> MP3
#
# Usage: ./client-understand.sh input.wav (or input.mp3)
#
# POST /understand (async job):
# input -> server-understand.json (audio codes + metadata)
#
# POST /synth (async job):
# server-understand.json + input -> server-understand.mp3
#
# Start the server first (./server.sh).
set -eu
if [ $# -lt 1 ]; then
echo "Usage: $0 <input.wav|input.mp3>"
exit 1
fi
HOST="http://127.0.0.1:8085"
input="$1"
# poll a job until done, exit 1 on failure
wait_job() {
local id="$1"
while true; do
status=$(curl -sf "${HOST}/job?id=${id}" | jq -r '.status')
case "$status" in
done) return 0 ;;
failed|cancelled) echo "Job ${id}: ${status}"; return 1 ;;
esac
sleep 2
done
}
# understand: submit, poll, fetch result
UND_ID=$(curl -sf "${HOST}/understand" \
-F "audio=@${input}" | jq -r '.id')
echo "Understand job: ${UND_ID}"
wait_job "${UND_ID}"
curl -sf "${HOST}/job?id=${UND_ID}&result=1" -o server-understand.json
sed -i \
-e 's/"audio_cover_strength": *[0-9.]*/"audio_cover_strength": 0.04/' \
server-understand.json
# synth: submit, poll, fetch result
SYNTH_ID=$(curl -sf "${HOST}/synth" \
-F "request=@server-understand.json" \
-F "audio=@${input}" | jq -r '.id')
echo "Synth job: ${SYNTH_ID}"
wait_job "${SYNTH_ID}"
curl -sf "${HOST}/job?id=${SYNTH_ID}&result=1" -o server-understand.mp3
+36
View File
@@ -0,0 +1,36 @@
#!/bin/bash
# Test ace-server: LM enriches caption, synth renders to MP3.
# Start the server first (./server.sh), then run this.
set -eu
HOST="http://127.0.0.1:8085"
# poll a job until done, exit 1 on failure
wait_job() {
local id="$1"
while true; do
status=$(curl -sf "${HOST}/job?id=${id}" | jq -r '.status')
case "$status" in
done) return 0 ;;
failed|cancelled) echo "Job ${id}: ${status}"; return 1 ;;
esac
sleep 2
done
}
# LM: submit, poll, fetch result
LM_ID=$(curl -sf "${HOST}/lm" \
-H "Content-Type: application/json" \
-d @full-sft.json | jq -r '.id')
echo "LM job: ${LM_ID}"
wait_job "${LM_ID}"
curl -sf "${HOST}/job?id=${LM_ID}&result=1" | jq '.[0]' > server-lm0.json
# synth: submit, poll, fetch result
SYNTH_ID=$(curl -sf "${HOST}/synth" \
-H "Content-Type: application/json" \
-d @server-lm0.json | jq -r '.id')
echo "Synth job: ${SYNTH_ID}"
wait_job "${SYNTH_ID}"
curl -sf "${HOST}/job?id=${SYNTH_ID}&result=1" -o server0.mp3
+12
View File
@@ -0,0 +1,12 @@
{
"caption": "Ambient electronic soundscape with warm analog pads",
"lyrics": "",
"bpm": 90,
"duration": 180,
"keyscale": "C minor",
"timesignature": "4",
"vocal_language": "en",
"inference_steps": 50,
"guidance_scale": 1.0,
"shift": 1.0
}
+9
View File
@@ -0,0 +1,9 @@
#!/bin/bash
set -eu
../build/ace-synth \
--request dit-only-sft.json \
--embedding ../models/Qwen3-Embedding-0.6B-Q8_0.gguf \
--dit ../models/acestep-v15-sft-Q8_0.gguf \
--vae ../models/vae-BF16.gguf
+12
View File
@@ -0,0 +1,12 @@
{
"caption": "Ambient electronic soundscape with warm analog pads",
"lyrics": "",
"bpm": 90,
"duration": 180,
"keyscale": "C minor",
"timesignature": "4",
"vocal_language": "en",
"inference_steps": 8,
"guidance_scale": 1.0,
"shift": 3.0
}
+9
View File
@@ -0,0 +1,9 @@
#!/bin/bash
set -eu
../build/ace-synth \
--request dit-only.json \
--embedding ../models/Qwen3-Embedding-0.6B-Q8_0.gguf \
--dit ../models/acestep-v15-turbo-Q8_0.gguf \
--vae ../models/vae-BF16.gguf
+12
View File
@@ -0,0 +1,12 @@
{
"caption": "Upbeat French house with infectious disco-inspired bassline, crisp four-on-the-floor kick pattern, wah-wah filtered guitar riffs, retro synth stabs, soulful male lead vocals with gospel-style backing harmonies, smooth saxophone accents, warm vinyl crackle texture, bright summer vibe, polished modern mix with vintage analog warmth, driving yet laid-back energy perfect for rooftop parties and sunset drives",
"lyrics": "[Intro - Ligne de Basse Funk & Beat House]\n\n[Verse 1]\nSous le soleil de Paris, on danse sans fin\nLa nuit s'allume, le beat nous guide\nLes étoiles scintillent au rythme du kick\nUn sourire léger, tout est si vivant\n\n[Pre-Chorus]\nLaisse-toi porter par la musique qui chante\n\n[Chorus]\nOn danse sous le ciel étoilé\nLe monde s'arrête, on s'envole\nAvec ce groove qui nous emporte\nJusqu'au matin, on ne s'arrête pas\n\n[Verse 2]\nLa ville respire au son des cuivres légers\nLes mains en l'air, on oublie le temps\nLa basse funk nous secoue les pieds\nUn été éternel, rien ne peut nous briser\n\n[Chorus]\nOn danse sous le ciel étoilé\nLe monde s'arrête, on s'envole\nAvec ce groove qui nous emporte\nJusqu'au matin, on ne s'arrête pas\n\n[Guitar Solo - Wah-Wah Funk]\n\n[Bridge - Saxophone & Cordes]\nRespire profondément, l'univers t'appelle\n\n[Outro - Synth Fade avec Craquement Vinyle]",
"duration": 240,
"bpm": 124,
"vocal_language": "fr",
"keyscale": "F# major",
"timesignature": "4",
"inference_steps": 50,
"guidance_scale": 1.0,
"shift": 1.0
}
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
set -eu
../build/ace-lm \
--request full-sft.json \
--lm ../models/acestep-5Hz-lm-4B-Q8_0.gguf
../build/ace-synth \
--request full-sft0.json \
--embedding ../models/Qwen3-Embedding-0.6B-Q8_0.gguf \
--dit ../models/acestep-v15-sft-Q8_0.gguf \
--vae ../models/vae-BF16.gguf
+12
View File
@@ -0,0 +1,12 @@
{
"caption": "Upbeat French house with infectious disco-inspired bassline, crisp four-on-the-floor kick pattern, wah-wah filtered guitar riffs, retro synth stabs, soulful male lead vocals with gospel-style backing harmonies, smooth saxophone accents, warm vinyl crackle texture, bright summer vibe, polished modern mix with vintage analog warmth, driving yet laid-back energy perfect for rooftop parties and sunset drives",
"lyrics": "[Intro - Ligne de Basse Funk & Beat House]\n\n[Verse 1]\nSous le soleil de Paris, on danse sans fin\nLa nuit s'allume, le beat nous guide\nLes étoiles scintillent au rythme du kick\nUn sourire léger, tout est si vivant\n\n[Pre-Chorus]\nLaisse-toi porter par la musique qui chante\n\n[Chorus]\nOn danse sous le ciel étoilé\nLe monde s'arrête, on s'envole\nAvec ce groove qui nous emporte\nJusqu'au matin, on ne s'arrête pas\n\n[Verse 2]\nLa ville respire au son des cuivres légers\nLes mains en l'air, on oublie le temps\nLa basse funk nous secoue les pieds\nUn été éternel, rien ne peut nous briser\n\n[Chorus]\nOn danse sous le ciel étoilé\nLe monde s'arrête, on s'envole\nAvec ce groove qui nous emporte\nJusqu'au matin, on ne s'arrête pas\n\n[Guitar Solo - Wah-Wah Funk]\n\n[Bridge - Saxophone & Cordes]\nRespire profondément, l'univers t'appelle\n\n[Outro - Synth Fade avec Craquement Vinyle]",
"duration": 240,
"bpm": 124,
"vocal_language": "fr",
"keyscale": "F# major",
"timesignature": "4",
"inference_steps": 8,
"guidance_scale": 1.0,
"shift": 3.0
}
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
set -eu
../build/ace-lm \
--request full.json \
--lm ../models/acestep-5Hz-lm-4B-Q8_0.gguf
../build/ace-synth \
--request full0.json \
--embedding ../models/Qwen3-Embedding-0.6B-Q8_0.gguf \
--dit ../models/acestep-v15-turbo-Q8_0.gguf \
--vae ../models/vae-BF16.gguf
+9
View File
@@ -0,0 +1,9 @@
{
"caption": "electric guitar riff, funk guitar, house music, instrumental",
"lyrics": "[Instrumental]",
"task_type": "lego",
"track": "guitar",
"inference_steps": 50,
"guidance_scale": 1.0,
"shift": 1.0
}
+33
View File
@@ -0,0 +1,33 @@
#!/bin/bash
# Generate a source track, then lego a guitar stem over it
#
# Note: lego requires acestep-v15-base; turbo/sft do not support it
#
# LM + DiT phase (source track):
# simple.json -> simple0.json -> simple00.wav
#
# Lego phase (guitar stem over source):
# lego.json + simple00.wav -> lego0.wav
set -eu
# Phase 1: generate a source track with the simple prompt
../build/ace-lm \
--request simple.json \
--lm ../models/acestep-5Hz-lm-4B-Q8_0.gguf
../build/ace-synth \
--request simple0.json \
--embedding ../models/Qwen3-Embedding-0.6B-Q8_0.gguf \
--dit ../models/acestep-v15-turbo-Q8_0.gguf \
--vae ../models/vae-BF16.gguf \
--format wav16
# Phase 2: lego guitar on the generated track (base model required)
../build/ace-synth \
--src-audio simple00.wav \
--request lego.json \
--embedding ../models/Qwen3-Embedding-0.6B-Q8_0.gguf \
--dit ../models/acestep-v15-base-Q8_0.gguf \
--vae ../models/vae-BF16.gguf \
--format wav16
+9
View File
@@ -0,0 +1,9 @@
{
"caption": "Hard-hitting hip hop track with deep 808 bass, crisp trap hi-hats, heavy snare rolls, dark piano melody, and confident aggressive vocal delivery",
"lyrics": "[Intro]\nYeah... c'est comme ca...\n\n[Verse 1]\nJe marche dans la ville quand le soleil se couche\nLes lumieres s'allument j'ai les mots dans la bouche\nOn m'a dit fais attention le monde est pas facile\nJ'ai repondu tranquille j'ai grandi dans la ville\nLes murs ont des oreilles les rues ont des histoires\nChaque coin chaque angle chaque bout de trottoir\nJ'ai vu des gens tomber j'ai vu des gens se lever\nMoi je reste debout j'ai pas le temps de plier\n\n[Chorus]\nOn avance on recule pas\nLa vie nous teste a chaque pas\nOn avance on recule pas\nRegarde devant oublie tout ca\n\n[Verse 2]\nLe reveil sonne tot le cafe brule les levres\nLe metro le boulot la routine la fievre\nMais le soir dans ma chambre je reprends mon stylo\nJe pose sur le papier tout ce que j'ai sur le dos\nMes reves sont plus grands que les murs de ma chambre\nPlus chauds que juillet plus forts que decembre\nOn m'a dit sois realiste range tes illusions\nJ'ai repondu ma vie c'est pas de la fiction\n\n[Chorus]\nOn avance on recule pas\nLa vie nous teste a chaque pas\nOn avance on recule pas\nRegarde devant oublie tout ca\n\n[Outro]\nYeah... on lache rien... jamais...",
"duration": 200,
"vocal_language": "fr",
"inference_steps": 50,
"guidance_scale": 1.0,
"shift": 1.0
}
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
set -eu
../build/ace-lm \
--request partial-sft.json \
--lm ../models/acestep-5Hz-lm-4B-Q8_0.gguf
../build/ace-synth \
--request partial-sft0.json \
--embedding ../models/Qwen3-Embedding-0.6B-Q8_0.gguf \
--dit ../models/acestep-v15-sft-Q8_0.gguf \
--vae ../models/vae-BF16.gguf
+9
View File
@@ -0,0 +1,9 @@
{
"caption": "Hard-hitting hip hop track with deep 808 bass, crisp trap hi-hats, heavy snare rolls, dark piano melody, and confident aggressive vocal delivery",
"lyrics": "[Intro]\nYeah... c'est comme ca...\n\n[Verse 1]\nJe marche dans la ville quand le soleil se couche\nLes lumieres s'allument j'ai les mots dans la bouche\nOn m'a dit fais attention le monde est pas facile\nJ'ai repondu tranquille j'ai grandi dans la ville\nLes murs ont des oreilles les rues ont des histoires\nChaque coin chaque angle chaque bout de trottoir\nJ'ai vu des gens tomber j'ai vu des gens se lever\nMoi je reste debout j'ai pas le temps de plier\n\n[Chorus]\nOn avance on recule pas\nLa vie nous teste a chaque pas\nOn avance on recule pas\nRegarde devant oublie tout ca\n\n[Verse 2]\nLe reveil sonne tot le cafe brule les levres\nLe metro le boulot la routine la fievre\nMais le soir dans ma chambre je reprends mon stylo\nJe pose sur le papier tout ce que j'ai sur le dos\nMes reves sont plus grands que les murs de ma chambre\nPlus chauds que juillet plus forts que decembre\nOn m'a dit sois realiste range tes illusions\nJ'ai repondu ma vie c'est pas de la fiction\n\n[Chorus]\nOn avance on recule pas\nLa vie nous teste a chaque pas\nOn avance on recule pas\nRegarde devant oublie tout ca\n\n[Outro]\nYeah... on lache rien... jamais...",
"duration": 200,
"vocal_language": "fr",
"inference_steps": 8,
"guidance_scale": 1.0,
"shift": 3.0
}
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
set -eu
../build/ace-lm \
--request partial.json \
--lm ../models/acestep-5Hz-lm-4B-Q8_0.gguf
../build/ace-synth \
--request partial0.json \
--embedding ../models/Qwen3-Embedding-0.6B-Q8_0.gguf \
--dit ../models/acestep-v15-turbo-Q8_0.gguf \
--vae ../models/vae-BF16.gguf
+8
View File
@@ -0,0 +1,8 @@
{
"caption": "Upbeat pop rock anthem with driving electric guitars, punchy drums, catchy vocal hooks, and a singalong chorus",
"vocal_language": "fr",
"lm_batch_size": 2,
"inference_steps": 8,
"guidance_scale": 1.0,
"shift": 3.0
}
+23
View File
@@ -0,0 +1,23 @@
#!/bin/bash
# Generate 2 songs: LM produces 2 enriched requests (different codes/metas),
# DiT renders them in a single GPU batch.
#
# LM phase (lm_batch_size=2 in simple-batch.json):
# simple-batch.json -> simple-batch0.json, simple-batch1.json
#
# DiT phase (both requests in one batch):
# simple-batch0.json + simple-batch1.json -> simple-batch00.mp3, simple-batch11.mp3
set -eu
# Phase 1: LM generates 2 variations (different lyrics/codes/metas)
../build/ace-lm \
--request simple-batch.json \
--lm ../models/acestep-5Hz-lm-4B-Q8_0.gguf
# Phase 2: DiT+VAE renders both in one GPU batch
../build/ace-synth \
--request simple-batch0.json simple-batch1.json \
--embedding ../models/Qwen3-Embedding-0.6B-Q8_0.gguf \
--dit ../models/acestep-v15-turbo-Q8_0.gguf \
--vae ../models/vae-BF16.gguf
+7
View File
@@ -0,0 +1,7 @@
{
"caption": "Upbeat pop rock anthem with driving electric guitars, punchy drums, catchy vocal hooks, and a singalong chorus",
"vocal_language": "fr",
"inference_steps": 50,
"guidance_scale": 1.0,
"shift": 1.0
}
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
set -eu
../build/ace-lm \
--request simple-sft.json \
--lm ../models/acestep-5Hz-lm-4B-Q8_0.gguf
../build/ace-synth \
--request simple-sft0.json \
--embedding ../models/Qwen3-Embedding-0.6B-Q8_0.gguf \
--dit ../models/acestep-v15-sft-Q8_0.gguf \
--vae ../models/vae-BF16.gguf
+15
View File
@@ -0,0 +1,15 @@
@echo off
set PATH=%~dp0..\build\Release;%PATH%
ace-lm.exe ^
--request simple.json ^
--lm ..\models\acestep-5Hz-lm-4B-Q6_K.gguf
ace-synth.exe ^
--request simple0.json ^
--embedding ..\models\Qwen3-Embedding-0.6B-Q8_0.gguf ^
--dit ..\models\acestep-v15-turbo-Q6_K.gguf ^
--vae ..\models\vae-BF16.gguf
pause
+7
View File
@@ -0,0 +1,7 @@
{
"caption": "Upbeat pop rock anthem with driving electric guitars, punchy drums, catchy vocal hooks, and a singalong chorus",
"vocal_language": "fr",
"inference_steps": 8,
"guidance_scale": 1.0,
"shift": 3.0
}
+13
View File
@@ -0,0 +1,13 @@
#!/bin/bash
set -eu
../build/ace-lm \
--request simple.json \
--lm ../models/acestep-5Hz-lm-4B-Q8_0.gguf
../build/ace-synth \
--request simple0.json \
--embedding ../models/Qwen3-Embedding-0.6B-Q8_0.gguf \
--dit ../models/acestep-v15-turbo-Q8_0.gguf \
--vae ../models/vae-BF16.gguf