Spaces:
Sleeping
Sleeping
Dylan Deshler commited on
Commit ·
95e3962
1
Parent(s): 9dd435f
autoregressive
Browse files- backend.py +52 -15
- real_backend.py +87 -54
backend.py
CHANGED
|
@@ -77,6 +77,16 @@ N_CHUNKS = 24 # fixed sequence length (measures) -- matches training
|
|
| 77 |
# positions the model never trained on. Continuation therefore SLIDES a fixed
|
| 78 |
# 24-measure window instead of growing it.
|
| 79 |
CONTINUE_MEASURES = 8
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
# Style embedding width. The DiT is now conditioned on CLAP embeddings
|
| 81 |
# (clap.CLAP proj_dim=512), NOT the old 128-d contrast.py vectors. Both stage
|
| 82 |
# checkpoints carry style_dim=512 in their model_args; keep this in sync.
|
|
@@ -131,26 +141,53 @@ def shift_window(c: "Conditioning", n_new: int) -> "Conditioning":
|
|
| 131 |
"""Slide a conditioning window forward by `n_new` measures.
|
| 132 |
|
| 133 |
The first T-n_new slots become the OLD window's tail -- those are the
|
| 134 |
-
measures the model
|
| 135 |
-
|
| 136 |
-
|
| 137 |
-
|
| 138 |
-
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
| 142 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 143 |
T = c.T
|
| 144 |
n_new = max(1, min(int(n_new), T - 1))
|
| 145 |
n_ctx = T - n_new
|
|
|
|
|
|
|
| 146 |
new = c.copy()
|
| 147 |
for s in Conditioning._NPZ_SIGNALS:
|
| 148 |
arr, old = getattr(new, s), getattr(c, s)
|
| 149 |
arr[:n_ctx] = old[n_new:]
|
| 150 |
-
|
|
|
|
|
|
|
|
|
|
| 151 |
for s in ALL_SIGNALS:
|
| 152 |
-
|
| 153 |
-
|
|
|
|
| 154 |
return new
|
| 155 |
|
| 156 |
|
|
@@ -294,7 +331,7 @@ class Track:
|
|
| 294 |
# (guidance 3.0 matches training's `{i}_cfg.wav`). MockBackend ignores it.
|
| 295 |
guidance: float = 3.0
|
| 296 |
# Cached model latents (B=1, T, N, C) from the last render. Used by
|
| 297 |
-
# RealBackend
|
| 298 |
latents: Optional[np.ndarray] = None
|
| 299 |
|
| 300 |
# ---- continuation ------------------------------------------------------
|
|
@@ -778,8 +815,8 @@ class MockBackend(ModelBackend):
|
|
| 778 |
|
| 779 |
def regenerate_region(self, track, start, end, seed, n_steps=100):
|
| 780 |
"""Mock inpaint: keep audio outside [start,end), re-render inside with a
|
| 781 |
-
new seed. The real backend resamples only those latents
|
| 782 |
-
|
| 783 |
tr = track.copy()
|
| 784 |
s, e = self._range(start, end, tr.cond.T)
|
| 785 |
full, bounds = self._synthesize(tr.cond, seed=seed) # fresh noise render
|
|
|
|
| 77 |
# positions the model never trained on. Continuation therefore SLIDES a fixed
|
| 78 |
# 24-measure window instead of growing it.
|
| 79 |
CONTINUE_MEASURES = 8
|
| 80 |
+
|
| 81 |
+
# Noise level the already-written measures are held at while the new ones are
|
| 82 |
+
# sampled. 0.0 == hand the past over perfectly clean, which is what makes the
|
| 83 |
+
# re-decoded context bit-match the audio already in the mix. Diffusion Forcing's
|
| 84 |
+
# stabilization result is that a SMALL nonzero level makes long autoregressive
|
| 85 |
+
# rollouts more robust (the model stops trusting its own artifacts), so if
|
| 86 |
+
# repeated Continues harden into a loop or drift, try 0.02-0.1. See
|
| 87 |
+
# real_backend.fm_df_sample.
|
| 88 |
+
CONTINUE_CTX_NOISE = 0.0
|
| 89 |
+
|
| 90 |
# Style embedding width. The DiT is now conditioned on CLAP embeddings
|
| 91 |
# (clap.CLAP proj_dim=512), NOT the old 128-d contrast.py vectors. Both stage
|
| 92 |
# checkpoints carry style_dim=512 in their model_args; keep this in sync.
|
|
|
|
| 141 |
"""Slide a conditioning window forward by `n_new` measures.
|
| 142 |
|
| 143 |
The first T-n_new slots become the OLD window's tail -- those are the
|
| 144 |
+
measures handed to the model as fixed context, so their conditioning has to
|
| 145 |
+
travel with their latents or the model is told one thing and shown another.
|
| 146 |
+
Values and per-measure `active` flags both shift.
|
| 147 |
+
|
| 148 |
+
The n_new slots exposed at the end are the ones being WRITTEN, and what goes
|
| 149 |
+
in them is a real decision:
|
| 150 |
+
|
| 151 |
+
style, bpm -- carried forward from the last context measure, active flag
|
| 152 |
+
included. These are properties of the piece, not
|
| 153 |
+
descriptions of a particular bar; a continuation should
|
| 154 |
+
stay in the same style and the same tempo unless asked
|
| 155 |
+
otherwise, and bpm additionally has to hold a real number
|
| 156 |
+
because it sets the decoded measure duration.
|
| 157 |
+
|
| 158 |
+
chroma, rms, density, zcr, flatness -- turned OFF (free). These describe
|
| 159 |
+
what a bar actually contains, and nobody knows that for a
|
| 160 |
+
bar that has not been written yet. Copying the previous
|
| 161 |
+
eight bars' values forward would assert the new bars have
|
| 162 |
+
the same chords, the same energy and the same texture as
|
| 163 |
+
the ones they follow, which is both a claim we cannot make
|
| 164 |
+
and a direct instruction to repeat. Freeing them swaps in
|
| 165 |
+
the null token and clears the stage-2 presence channel,
|
| 166 |
+
which is in-distribution (training dropped signals per
|
| 167 |
+
token, p_ind_uncond=0.5 at stage 2) and lets the frozen
|
| 168 |
+
context latents decide the continuation instead.
|
| 169 |
+
|
| 170 |
+
The freed values still get back-filled from the render by
|
| 171 |
+
`_measure_render`, so after a Continue the curves show what the model
|
| 172 |
+
actually played and are immediately editable -- shape them and hit
|
| 173 |
+
Regenerate to push the new bars somewhere else."""
|
| 174 |
T = c.T
|
| 175 |
n_new = max(1, min(int(n_new), T - 1))
|
| 176 |
n_ctx = T - n_new
|
| 177 |
+
last = n_ctx - 1 # last context measure, post-shift
|
| 178 |
+
carry = ("style", "bpm")
|
| 179 |
new = c.copy()
|
| 180 |
for s in Conditioning._NPZ_SIGNALS:
|
| 181 |
arr, old = getattr(new, s), getattr(c, s)
|
| 182 |
arr[:n_ctx] = old[n_new:]
|
| 183 |
+
# seed every new slot from the last context measure. For style/bpm that
|
| 184 |
+
# IS the conditioning; for the freed signals it is just a placeholder so
|
| 185 |
+
# the arrays hold something plausible until the render overwrites them.
|
| 186 |
+
arr[n_ctx:] = arr[last]
|
| 187 |
for s in ALL_SIGNALS:
|
| 188 |
+
a = new.active[s]
|
| 189 |
+
a[:n_ctx] = c.active[s][n_new:]
|
| 190 |
+
a[n_ctx:] = a[last] if s in carry else False
|
| 191 |
return new
|
| 192 |
|
| 193 |
|
|
|
|
| 331 |
# (guidance 3.0 matches training's `{i}_cfg.wav`). MockBackend ignores it.
|
| 332 |
guidance: float = 3.0
|
| 333 |
# Cached model latents (B=1, T, N, C) from the last render. Used by
|
| 334 |
+
# RealBackend to freeze measures during region regen / continuation.
|
| 335 |
latents: Optional[np.ndarray] = None
|
| 336 |
|
| 337 |
# ---- continuation ------------------------------------------------------
|
|
|
|
| 815 |
|
| 816 |
def regenerate_region(self, track, start, end, seed, n_steps=100):
|
| 817 |
"""Mock inpaint: keep audio outside [start,end), re-render inside with a
|
| 818 |
+
new seed. The real backend resamples only those latents, holding the
|
| 819 |
+
kept measures clean at noise level ~0 -- see RealBackend notes."""
|
| 820 |
tr = track.copy()
|
| 821 |
s, e = self._range(start, end, tr.cond.T)
|
| 822 |
full, bounds = self._synthesize(tr.cond, seed=seed) # fresh noise render
|
real_backend.py
CHANGED
|
@@ -90,7 +90,8 @@ import numpy as np
|
|
| 90 |
|
| 91 |
from backend import (
|
| 92 |
ModelBackend, Track, Conditioning,
|
| 93 |
-
ALL_SIGNALS, CONTINUE_MEASURES, EDITABLE_SIGNALS,
|
|
|
|
| 94 |
TARGET_SIG, SR,
|
| 95 |
bpm_curve, eval_shape, shift_window,
|
| 96 |
)
|
|
@@ -127,13 +128,13 @@ def _crossfade_segments(segment_a, segment_b, sample_rate, crossfade_ms=15):
|
|
| 127 |
|
| 128 |
|
| 129 |
# =============================================================================
|
| 130 |
-
#
|
| 131 |
-
# untouched
|
| 132 |
# =============================================================================
|
| 133 |
-
def
|
| 134 |
diffusion, # FM instance (net wrapper's .diffusion)
|
| 135 |
net, # the raw DiT (wrapper.net)
|
| 136 |
-
known_x0, # (B, T, N, C) clean latents to preserve
|
| 137 |
keep_mask, # (B, T, 1, 1) bool: True where latents are FROZEN (kept)
|
| 138 |
n_steps,
|
| 139 |
net_kwargs=None,
|
|
@@ -144,15 +145,45 @@ def fm_inpaint_sample(
|
|
| 144 |
rescale_phi=0.0,
|
| 145 |
cfg_mode="independent",
|
| 146 |
t_dist="uniform",
|
| 147 |
-
|
| 148 |
):
|
| 149 |
-
"""
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
|
| 154 |
-
|
| 155 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 156 |
|
| 157 |
Returns x0-space latents (B, T, N, C)."""
|
| 158 |
import torch
|
|
@@ -170,42 +201,41 @@ def fm_inpaint_sample(
|
|
| 170 |
t_steps[0] = 1.0
|
| 171 |
t_steps[-1] = 0.0
|
| 172 |
|
| 173 |
-
keep = keep_mask.to(dev)
|
|
|
|
|
|
|
| 174 |
|
| 175 |
-
|
| 176 |
-
|
| 177 |
-
|
| 178 |
-
|
| 179 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 180 |
|
| 181 |
with torch.no_grad():
|
| 182 |
-
|
| 183 |
-
x_t = torch.where(keep, _noised_known(t_steps[0]), x_t)
|
| 184 |
for i in range(n_steps):
|
| 185 |
t_cur, t_next = t_steps[i], t_steps[i + 1]
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
|
| 190 |
-
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
step_up = (diffusion.sigma(t_cur) / diffusion.sigma(t_next)).clamp(max=5.0)
|
| 204 |
-
x_t = x_next + torch.randn_like(x_next) * (
|
| 205 |
-
diffusion.sigma(t_cur) - diffusion.sigma(t_next))
|
| 206 |
-
x_t = torch.where(keep, _noised_known(t_cur), x_t)
|
| 207 |
-
else:
|
| 208 |
-
x_t = x_next
|
| 209 |
return x_t
|
| 210 |
|
| 211 |
|
|
@@ -920,7 +950,7 @@ class RealBackend(ModelBackend):
|
|
| 920 |
return (out / (np.linalg.norm(out) + 1e-9)).astype(np.float32)
|
| 921 |
|
| 922 |
# =====================================================================
|
| 923 |
-
# region regenerate ==
|
| 924 |
# =====================================================================
|
| 925 |
def regenerate_region(self, track, start, end, seed, n_steps=SAMPLE_STEPS):
|
| 926 |
import torch
|
|
@@ -945,11 +975,12 @@ class RealBackend(ModelBackend):
|
|
| 945 |
self._sampling_args(c, getattr(tr, "guidance", None))
|
| 946 |
|
| 947 |
with self._ctx():
|
| 948 |
-
y =
|
| 949 |
self.diffusion, self.net, known_x0, keep, n_steps,
|
| 950 |
net_kwargs=cfg_net_kwargs, uncond_net_kwargs=uncond_net_kwargs,
|
| 951 |
guidance=guidances, noise=noise, memory_efficient=False,
|
| 952 |
-
cfg_mode=cfg_mode, t_dist=self.t_dist,
|
|
|
|
| 953 |
|
| 954 |
bpm_row = torch.from_numpy(
|
| 955 |
np.asarray(c.bpm, dtype=np.float32))[None].to(self.device)
|
|
@@ -978,11 +1009,12 @@ class RealBackend(ModelBackend):
|
|
| 978 |
FROZEN latents sampled
|
| 979 |
|
| 980 |
The 24-n_new context measures keep their exact latents from the previous
|
| 981 |
-
render and are
|
| 982 |
-
|
| 983 |
-
|
| 984 |
-
|
| 985 |
-
|
|
|
|
| 986 |
|
| 987 |
Only the newly sampled tail is appended to the song; the context
|
| 988 |
measures are already in the mix and get re-decoded solely because the
|
|
@@ -1020,11 +1052,12 @@ class RealBackend(ModelBackend):
|
|
| 1020 |
self._sampling_args(c, getattr(tr, "guidance", None))
|
| 1021 |
|
| 1022 |
with self._ctx():
|
| 1023 |
-
y =
|
| 1024 |
self.diffusion, self.net, known_x0, keep, n_steps,
|
| 1025 |
net_kwargs=cfg_net_kwargs, uncond_net_kwargs=uncond_net_kwargs,
|
| 1026 |
guidance=guidances, noise=noise, memory_efficient=False,
|
| 1027 |
-
cfg_mode=cfg_mode, t_dist=self.t_dist,
|
|
|
|
| 1028 |
|
| 1029 |
bpm_row = torch.from_numpy(
|
| 1030 |
np.asarray(c.bpm, dtype=np.float32))[None].to(self.device)
|
|
|
|
| 90 |
|
| 91 |
from backend import (
|
| 92 |
ModelBackend, Track, Conditioning,
|
| 93 |
+
ALL_SIGNALS, CONTINUE_CTX_NOISE, CONTINUE_MEASURES, EDITABLE_SIGNALS,
|
| 94 |
+
N_CHUNKS, STYLE_DIM,
|
| 95 |
TARGET_SIG, SR,
|
| 96 |
bpm_curve, eval_shape, shift_window,
|
| 97 |
)
|
|
|
|
| 128 |
|
| 129 |
|
| 130 |
# =============================================================================
|
| 131 |
+
# Masked sampler, DIFFUSION-FORCING style. Standalone so diffusion_forcing.py
|
| 132 |
+
# stays untouched; uses the same FM diffusion + get_prediction/CFG machinery.
|
| 133 |
# =============================================================================
|
| 134 |
+
def fm_df_sample(
|
| 135 |
diffusion, # FM instance (net wrapper's .diffusion)
|
| 136 |
net, # the raw DiT (wrapper.net)
|
| 137 |
+
known_x0, # (B, T, N, C) clean latents to preserve where kept
|
| 138 |
keep_mask, # (B, T, 1, 1) bool: True where latents are FROZEN (kept)
|
| 139 |
n_steps,
|
| 140 |
net_kwargs=None,
|
|
|
|
| 145 |
rescale_phi=0.0,
|
| 146 |
cfg_mode="independent",
|
| 147 |
t_dist="uniform",
|
| 148 |
+
ctx_noise=0.0, # noise level to hold the context at; see below
|
| 149 |
):
|
| 150 |
+
"""Masked FM sampling with a PER-MEASURE noise level.
|
| 151 |
+
|
| 152 |
+
This model is a diffusion-forcing model, and that is the whole point of it.
|
| 153 |
+
FM.loss draws
|
| 154 |
+
|
| 155 |
+
t = torch.sigmoid(torch.randn(B, T)) # (B, T) -- one per measure
|
| 156 |
+
|
| 157 |
+
so every measure was trained at its OWN independently-sampled noise level,
|
| 158 |
+
and MetaConditionalModernDiTV2 modulates per measure to match (`t = t +
|
| 159 |
+
style + bpm`, then `t[:, :, None]` broadcast across that measure's latent
|
| 160 |
+
positions). Attention is fully bidirectional, so a clean measure and a
|
| 161 |
+
pure-noise measure can sit in the same sequence and the clean one is read as
|
| 162 |
+
clean. Conditioning on the past is therefore NATIVE: hand the context
|
| 163 |
+
measures over at t~0 with their real latents and denoise only the rest.
|
| 164 |
+
|
| 165 |
+
That is what this does. The context is pinned to `known_x0` UNCHANGED at
|
| 166 |
+
every Euler step and reported at noise level `ctx_noise`, while the free
|
| 167 |
+
measures walk the schedule from t=1 down to 0.
|
| 168 |
+
|
| 169 |
+
Why not RePaint (which is what this function used to do): RePaint exists
|
| 170 |
+
because ordinary diffusion models accept a single scalar t, so the only way
|
| 171 |
+
to express "this part is known" is to forward-noise the known part to the
|
| 172 |
+
same level as the part being generated and splice it in. Here that is both
|
| 173 |
+
unnecessary and actively destructive -- at the first step (t=1) the context
|
| 174 |
+
gets noised to t=1, i.e. handed over as pure noise, so the model has no past
|
| 175 |
+
to condition on exactly when the global structure is being decided. It also
|
| 176 |
+
redraws that noise every step, so what context does survive flickers. Uniform
|
| 177 |
+
t is in-distribution for training (all-equal is one draw of (B,T) among
|
| 178 |
+
many), but it throws away the one capability that makes rollout work.
|
| 179 |
+
|
| 180 |
+
ctx_noise: 0.0 hands the context over clean. Diffusion Forcing's stabilization
|
| 181 |
+
result is that a SMALL nonzero level on the history makes long autoregressive
|
| 182 |
+
rollouts more robust -- the model treats its own past output as uncertain
|
| 183 |
+
instead of trusting artifacts -- so if repeated Continues drift or harden,
|
| 184 |
+
try ~0.02-0.1 (CONTINUE_CTX_NOISE in backend.py). Held clean at 0.0 the
|
| 185 |
+
context latents are bit-exact, which is what lets the re-decoded context
|
| 186 |
+
match the audio already in the mix.
|
| 187 |
|
| 188 |
Returns x0-space latents (B, T, N, C)."""
|
| 189 |
import torch
|
|
|
|
| 201 |
t_steps[0] = 1.0
|
| 202 |
t_steps[-1] = 0.0
|
| 203 |
|
| 204 |
+
keep = keep_mask.to(dev) # (B, T, 1, 1)
|
| 205 |
+
keep_row = keep[:, :, 0, 0] # (B, T) -- for the t vector
|
| 206 |
+
ctx_noise = float(ctx_noise)
|
| 207 |
|
| 208 |
+
# The context at level `ctx_noise`. Drawn ONCE, not per step: the context is
|
| 209 |
+
# a fixed thing the model is reading, not a quantity being resampled. At the
|
| 210 |
+
# default 0.0 this is exactly known_x0 (alpha(0)=1, sigma(0)=sigma_min=1e-5).
|
| 211 |
+
if ctx_noise <= 0.0:
|
| 212 |
+
ctx_x = known_x0
|
| 213 |
+
else:
|
| 214 |
+
tt = torch.full((B, T, N, 1), ctx_noise, device=dev, dtype=known_x0.dtype)
|
| 215 |
+
ctx_x = (diffusion.alpha(tt) * known_x0
|
| 216 |
+
+ diffusion.sigma(tt) * torch.randn_like(known_x0))
|
| 217 |
|
| 218 |
with torch.no_grad():
|
| 219 |
+
x_t = torch.where(keep, ctx_x, x_t)
|
|
|
|
| 220 |
for i in range(n_steps):
|
| 221 |
t_cur, t_next = t_steps[i], t_steps[i + 1]
|
| 222 |
+
# per-measure noise level: context sits at ctx_noise, free measures
|
| 223 |
+
# at wherever the schedule currently is.
|
| 224 |
+
t = torch.where(keep_row, torch.full_like(keep_row, ctx_noise,
|
| 225 |
+
dtype=x_t.dtype),
|
| 226 |
+
t_cur.to(x_t.dtype))
|
| 227 |
+
neg_v = diffusion.get_prediction(
|
| 228 |
+
net, x_t, t,
|
| 229 |
+
net_kwargs=net_kwargs,
|
| 230 |
+
uncond_net_kwargs=uncond_net_kwargs,
|
| 231 |
+
guidance=guidance,
|
| 232 |
+
memory_efficient=memory_efficient,
|
| 233 |
+
rescale_phi=rescale_phi,
|
| 234 |
+
cfg_mode=cfg_mode,
|
| 235 |
+
)
|
| 236 |
+
x_t = x_t + neg_v * (t_next - t_cur)
|
| 237 |
+
# the Euler step moved the context too; put it back untouched.
|
| 238 |
+
x_t = torch.where(keep, ctx_x, x_t)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 239 |
return x_t
|
| 240 |
|
| 241 |
|
|
|
|
| 950 |
return (out / (np.linalg.norm(out) + 1e-9)).astype(np.float32)
|
| 951 |
|
| 952 |
# =====================================================================
|
| 953 |
+
# region regenerate == masked resample of measure rows [start, end)
|
| 954 |
# =====================================================================
|
| 955 |
def regenerate_region(self, track, start, end, seed, n_steps=SAMPLE_STEPS):
|
| 956 |
import torch
|
|
|
|
| 975 |
self._sampling_args(c, getattr(tr, "guidance", None))
|
| 976 |
|
| 977 |
with self._ctx():
|
| 978 |
+
y = fm_df_sample(
|
| 979 |
self.diffusion, self.net, known_x0, keep, n_steps,
|
| 980 |
net_kwargs=cfg_net_kwargs, uncond_net_kwargs=uncond_net_kwargs,
|
| 981 |
guidance=guidances, noise=noise, memory_efficient=False,
|
| 982 |
+
cfg_mode=cfg_mode, t_dist=self.t_dist,
|
| 983 |
+
ctx_noise=CONTINUE_CTX_NOISE)
|
| 984 |
|
| 985 |
bpm_row = torch.from_numpy(
|
| 986 |
np.asarray(c.bpm, dtype=np.float32))[None].to(self.device)
|
|
|
|
| 1009 |
FROZEN latents sampled
|
| 1010 |
|
| 1011 |
The 24-n_new context measures keep their exact latents from the previous
|
| 1012 |
+
render and are handed to the model CLEAN, at noise level ~0, while the
|
| 1013 |
+
new measures denoise from t=1 -- diffusion forcing's per-measure noise
|
| 1014 |
+
level, which is what this model was trained for (see fm_df_sample). Same
|
| 1015 |
+
machinery region-regen uses, just with the free region pinned to the end
|
| 1016 |
+
of the window. So the new bars are conditioned on the actual audio that
|
| 1017 |
+
precedes them, not merely on a similar-looking conditioning curve.
|
| 1018 |
|
| 1019 |
Only the newly sampled tail is appended to the song; the context
|
| 1020 |
measures are already in the mix and get re-decoded solely because the
|
|
|
|
| 1052 |
self._sampling_args(c, getattr(tr, "guidance", None))
|
| 1053 |
|
| 1054 |
with self._ctx():
|
| 1055 |
+
y = fm_df_sample(
|
| 1056 |
self.diffusion, self.net, known_x0, keep, n_steps,
|
| 1057 |
net_kwargs=cfg_net_kwargs, uncond_net_kwargs=uncond_net_kwargs,
|
| 1058 |
guidance=guidances, noise=noise, memory_efficient=False,
|
| 1059 |
+
cfg_mode=cfg_mode, t_dist=self.t_dist,
|
| 1060 |
+
ctx_noise=CONTINUE_CTX_NOISE)
|
| 1061 |
|
| 1062 |
bpm_row = torch.from_numpy(
|
| 1063 |
np.asarray(c.bpm, dtype=np.float32))[None].to(self.device)
|