Spaces:
Running on Zero
Running on Zero
Dylan Deshler commited on
Commit ·
c9477d8
1
Parent(s): f5e4044
autoregressive
Browse files- backend.py +27 -17
- real_backend.py +19 -2
backend.py
CHANGED
|
@@ -79,25 +79,35 @@ N_CHUNKS = 24 # fixed sequence length (measures) -- matches training
|
|
| 79 |
CONTINUE_MEASURES = 8
|
| 80 |
|
| 81 |
# Noise level the already-written measures are held at while the new ones are
|
| 82 |
-
# sampled.
|
| 83 |
-
# reference implementation's shipped default (its scheduling matrix pads history
|
| 84 |
-
# with zeros; the `stabilization` variable exists but is set to 0) and the right
|
| 85 |
-
# default here.
|
| 86 |
#
|
| 87 |
-
#
|
| 88 |
-
#
|
| 89 |
-
#
|
| 90 |
-
#
|
| 91 |
-
# noise. This model gets that training for free: FM.loss draws an independent
|
| 92 |
-
# t ~ sigmoid(randn) per measure, so it has already seen every measure at every
|
| 93 |
-
# noise level and is calibrated for a past it should not fully trust.
|
| 94 |
#
|
| 95 |
-
#
|
| 96 |
-
#
|
| 97 |
-
#
|
| 98 |
-
#
|
| 99 |
-
#
|
| 100 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
|
| 102 |
# Vanilla history guidance (HG-v) weight for Continue. CFG steers toward the
|
| 103 |
# conditioning signals; this steers toward THE PAST:
|
|
|
|
| 79 |
CONTINUE_MEASURES = 8
|
| 80 |
|
| 81 |
# Noise level the already-written measures are held at while the new ones are
|
| 82 |
+
# sampled.
|
|
|
|
|
|
|
|
|
|
| 83 |
#
|
| 84 |
+
# NOT 0.0, even though clean history is what the Diffusion Forcing reference
|
| 85 |
+
# implementation ships. That implementation trains on DISCRETE noise indices
|
| 86 |
+
# drawn uniformly over [0, K), so index 0 -- perfectly clean -- is an ordinary
|
| 87 |
+
# training input for it. This model does not: FM.loss draws
|
|
|
|
|
|
|
|
|
|
| 88 |
#
|
| 89 |
+
# t = torch.sigmoid(torch.randn(B, T))
|
| 90 |
+
#
|
| 91 |
+
# a continuous logit-normal, which has ZERO density at 0 and never gets near it.
|
| 92 |
+
# Over a 300k-step run (grad_accum 4 x batch 32 x 24 measures ~= 9.2e8 draws) the
|
| 93 |
+
# smallest t the model ever saw is about 0.0025, and t < 0.001 never occurred at
|
| 94 |
+
# all. t=0.0 is therefore off the end of the training support, and t is not a
|
| 95 |
+
# passive tag: it feeds the per-measure AdaLN modulation (`t = t + style + bpm`),
|
| 96 |
+
# so an out-of-distribution value on the 16 context measures corrupts their
|
| 97 |
+
# features and, through attention, the free measures with them.
|
| 98 |
+
#
|
| 99 |
+
# 0.05 is the smallest value that is comfortably supported -- roughly 1.5e6
|
| 100 |
+
# training draws landed below it -- while leaving the context essentially intact
|
| 101 |
+
# (alpha=0.95, sigma=0.05). Draws below each level over that run:
|
| 102 |
+
#
|
| 103 |
+
# t < 0.001 0 t < 0.05 1,490,876
|
| 104 |
+
# t < 0.01 1,993 t < 0.10 12,904,433
|
| 105 |
+
#
|
| 106 |
+
# Raising it toward 0.1-0.2 is also well supported and is the knob to reach for
|
| 107 |
+
# if repeated Continues drift or harden into a loop (Diffusion Forcing's
|
| 108 |
+
# stabilization result: a model that half-distrusts its own past compounds error
|
| 109 |
+
# more slowly). Above ~0.3 the context genuinely washes out.
|
| 110 |
+
CONTINUE_CTX_NOISE = 0.05
|
| 111 |
|
| 112 |
# Vanilla history guidance (HG-v) weight for Continue. CFG steers toward the
|
| 113 |
# conditioning signals; this steers toward THE PAST:
|
real_backend.py
CHANGED
|
@@ -295,10 +295,27 @@ def fm_df_sample(
|
|
| 295 |
v_none = _predict(x_none, t_none)
|
| 296 |
v = v_none + omega * (v - v_none)
|
| 297 |
|
| 298 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 299 |
# the Euler step moved the context too; put it back untouched.
|
| 300 |
x_t = torch.where(keep, ctx_x, x_t)
|
| 301 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 302 |
|
| 303 |
|
| 304 |
def _check_stage(m, stage, path, model_args):
|
|
|
|
| 295 |
v_none = _predict(x_none, t_none)
|
| 296 |
v = v_none + omega * (v - v_none)
|
| 297 |
|
| 298 |
+
# (t_cur - t_next), NOT (t_next - t_cur). The net predicts -dx_t/dt
|
| 299 |
+
# (FM.loss's target is A(t)x + B(t)noise == x - (1-sigma_min)noise,
|
| 300 |
+
# commented "-dxt/dt"), and t runs 1 -> 0, so the descending step
|
| 301 |
+
# dt = t_next - t_cur is negative and the two negatives cancel:
|
| 302 |
+
# dx = (dx_t/dt) * dt = (-v) * (t_next - t_cur) = v * (t_cur - t_next)
|
| 303 |
+
# This is exactly what FMEulerSampler.sample does. Getting it
|
| 304 |
+
# backwards integrates the flow the wrong way and returns noise.
|
| 305 |
+
x_t = x_t + v * (t_cur - t_next)
|
| 306 |
# the Euler step moved the context too; put it back untouched.
|
| 307 |
x_t = torch.where(keep, ctx_x, x_t)
|
| 308 |
+
|
| 309 |
+
# Hand back the CLEAN context, not ctx_x. ctx_x is an input the model reads;
|
| 310 |
+
# it is not an answer. The caller stores this whole tensor as tr.latents and
|
| 311 |
+
# the next continuation slices its context out of it, so returning the noised
|
| 312 |
+
# copy would re-noise the same measures on every press: after k continues the
|
| 313 |
+
# oldest surviving measure has been scaled by alpha(ctx_noise)^k with k
|
| 314 |
+
# independent noise draws stacked on it (0.95^k at the 0.05 default -- 0.77
|
| 315 |
+
# by the fifth press) and has drifted well off the latent manifold. That
|
| 316 |
+
# decays into mush no matter how good the sampler is. It also means the
|
| 317 |
+
# re-decoded context measures are the real ones rather than degraded ones.
|
| 318 |
+
return torch.where(keep, known_x0, x_t)
|
| 319 |
|
| 320 |
|
| 321 |
def _check_stage(m, stage, path, model_args):
|