wikillm

Paper · 2025-01-31 · cs.CV, cs.GR

GestureLSM: Latent Shortcut based Co-Speech Gesture Generation with Spatial-Temporal Modeling

GestureLSM makes full-body co-speech gestures with flow matching over RVQ tokens of body regions. Spatial then temporal attention models region interactions; a shortcut self-consistency loss and Beta-skewed time sampling allow few sampling steps. Author-reported: FGD 4.088 on BEAT2, the lowest of the compared methods, and AIST 0.039 with 8 steps.

Flow matchingClassifier-free guidanceVector quantizationSelf-attentiongesture-generationmotion-generationflow-matchingshortcut-modelvector-quantizationbeat2

arXivPDFCodeMarkdown16 min read

AI-compiled by claude-haiku-5-5 on 2026-11-03, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.

In plain words

When people talk, their hands, arms, torso and legs move together. Most computer systems that generate such movement from speech handle each body part on its own, so the arms and hands can end up doing unrelated things.

GestureLSM splits the body into a few regions and turns each region's motion into a short sequence of codes. A transformer then works on all regions at once: at each moment it lets the regions see each other, and then it lets each region look at what it did in earlier frames. Speech conditions the whole process through attention.

The generator is trained with a flow-matching method: it learns to move from random noise to real motion along a path. A shortcut training rule teaches it to take larger steps along that path, so it needs few steps to produce a motion. The authors report that this gives better gesture quality than the baselines they compare with and runs faster than them.

TL;DR

  • Speech-driven full-body gesture generator on BEAT2. Body regions are tokenised with residual vector quantisation, and a transformer with spatial and temporal attention generates the tokens. §3.1 §3.2
  • Generation uses flow matching with a shortcut (self-consistency) objective and Beta-distributed training times. §3.3 eq. 4 eq. 6 eq. 7
  • Author-reported: FGD 4.088 (best of the nine compared methods in Table 1), BC 0.714, and AIST 0.039 at 8 sampling steps. tab. 1 §4.4
  • Code (MIT) is available. It differs from the paper in several places, including the speaker scope of the reported numbers. See Paper vs code.

Problem

Gesture generators that model each body part separately, or that model the whole body as one vector, produce unnatural and disconnected motion. Diffusion and autoregressive generators that run dozens of steps are slow. §1

The paper asks for coherent full-body gestures that are both high quality and fast to generate. §1 §3

Method

The method has three parts. Stage 1 tokenises the motion. Stage 2 is the gesture generator with spatial and temporal attention. Stage 3 trains it with a latent shortcut flow-matching objective. §3 fig. 3 fig. 4

Body-region tokenisation §3.1

The motion of each body region (upper body, hands, and legs in the text) is encoded by a convolutional encoder with two residual blocks. Each frame's vector is replaced by its nearest entry in a codebook, and a decoder maps the codes back to joint motion. §3.1 eq. 1 The paper uses residual vector quantisation (RVQ) but does not state the number of quantiser stages. §3.1 Per-region codebooks have 1,024 entries of width 128. app. B

The codebook assignment, for frame vector \mathbf{v}_t and codebook \{\mathbf{c}_i\}, is \tilde{\mathbf{v}}_t = \mathbf{c}_{i^*} with i^* = \arg\min_i \|\mathbf{c}_i - \mathbf{v}_t\|_2 §3.1. The decoder reconstructs joints from the quantised vectors, and this reconstruction is the round trip \mathcal{D}(\mathcal{Q}(\mathcal{E}(\cdot))) eq. 1.

Speech conditioning §3.1

Speech is represented by onset and amplitude features from the audio, and by word-level semantics from the transcript. Each has its own encoder. The two streams are combined by element-wise concatenation. The fused speech features enter the gesture features through several cross-attention layers in which the gesture features are queries and the speech features are keys and values. §3.1 The paper uses three cross-attention layers. app. B

Spatial and temporal attention §3.2

The generator is a transformer. Each block applies spatial attention first and temporal attention second, then a feed-forward network. §3.2 app. B

  • Spatial attention runs across body regions inside one frame. Time steps are treated as independent batch items, so the regions attend to each other at each moment. §3.2 eq. 2
  • Temporal attention runs along time for each region separately. Body regions are batch items. §3.2 eq. 3
  • Positional information is added before each attention. §3.2

\mathcal{A}_s = \mathrm{SoftMax}\!\left(\frac{Q_s K_s}{\sqrt{d}} + \mathbf{P}\right) V_s \qquad \text{[eq. 2]}

\mathcal{A}_t = \mathrm{SoftMax}\!\left(\frac{Q_t K_t}{\sqrt{d}} + \mathbf{P}\right) V_t \qquad \text{[eq. 3]}

Eqs. 2 and 3 are printed without the key transpose and with a single positional term \mathbf{P}. eq. 2 eq. 3 The sizes are n body regions, T time steps and feature dimension d. §3.2

The paper uses 8 spatial-temporal blocks. app. B

Flow matching and the latent shortcut §3.3

The flow path is linear: x_t = (1-t)\,x_0 + t\,x_1, where x_0 is Gaussian noise, x_1 is data and v_t = x_1 - x_0. §3.3

Flow matching regresses a network onto the velocity v_t. §3.3 eq. 4

\mathcal{L}^{F}(\theta) = \mathbb{E}_{x_0, x_1}\left[\left\| \bar{v}_\theta(x_t, t) - (x_1 - x_0) \right\|^2\right] \qquad \text{[eq. 4]}

A shortcut model also receives a step size d and predicts the displacement to x_t + d steps ahead along the flow. §3.3 eq. 5

x'_{t+d} = x_t + f_\theta(a, x_t, t, d) \qquad \text{[eq. 5]}

Self-consistency asks that one step of size 2d equal the average of two steps of size d. §3.3 eq. 6

f_\theta(a, x_t, t, 2d) = \tfrac{1}{2}\, f_\theta(a, x_t, t, d) + \tfrac{1}{2}\, f_\theta(a, x'_{t+d}, t, d) \qquad \text{[eq. 6]}

Here a is the speech condition. The paper's Eq. 6 writes the second argument as t; the code evaluates the second half-step at t + d. LSM.py eq. 6

Training times are drawn from a Beta distribution with density f(t;\alpha,\beta) on [0,1]. §3.3 eq. 7 The paper uses \alpha = 2 and \beta = 1.2. §3.3 tab. 2(c) The paper reports that the loss is highest near t = 1, which is why the skew emphasises that end of the path. §3.3 fig. 5

f(t;\alpha,\beta) = \frac{t^{\alpha-1}(1-t)^{\beta-1}}{\mathrm{B}(\alpha,\beta)}, \qquad t \in [0,1] \qquad \text{[eq. 7]}

Sampling uses Euler steps on the learned velocity. §3.3 The paper chooses 8 steps for inference. §4.4 tab. 2(f)

Training procedure as the code implements it

The paper does not spell out how the flow loss and the shortcut loss are combined in a batch. The official code does the following. [code: models/LSM.py#L352-L452]

Pseudocode
# Shortcut flow training step  [§3.3] [eq. 4] [eq. 6]
# Input:  latents (B, T, D) of RVQ codes  [§3.1]
#         speech features for the batch  [§3.1]
# Output: scalar loss  [code: models/LSM.py#L352-L452]

def training_step(latents, speech):
    # Gaussian noise, the start of the flow  [§3.3] [code: models/LSM.py#L367]
    noise = sample_gaussian(latents.shape)
    # Time per sample from Beta(2, 1.2), skewed towards t = 1  [§3.3] [eq. 7]
    time = sample_beta(alpha=2.0, beta=1.2, size=batch)
    # The first 3/4 of the batch is flow matching with step size 0;
    # the rest draws d from {1/2, 1/4, ..., 1/128}
    # [code: models/LSM.py#L352-L365]
    flow_count = int(batch * 3 / 4)
    step = sample_step_size(size=batch)
    step[:flow_count] = 0.0
    # Straight path from noise (t = 0) to data (t = 1)  [§3.3] [eq. 4]
    x_t = time * latents + (1 - time) * noise
    # Flow part: velocity regression, with the MSE divided by t  [eq. 4]
    # [code: models/LSM.py#L386-L392]
    speech_flow = drop_speech(speech[:flow_count], prob=0.1)
    velocity_pred = denoiser(x_t[:flow_count], time[:flow_count],
                             step[:flow_count], speech_flow)
    velocity_target = latents[:flow_count] - noise[:flow_count]
    flow_loss = mean(mse(velocity_pred, velocity_target)
                     / time[:flow_count])
    # Consistency part: 80% of its samples get the null speech embedding
    # [code: models/LSM.py#L398-L403]
    speech_cons = force_null(speech[flow_count:], prob=0.8)
    # Target: two half steps of size d, averaged; no gradient  [eq. 6]
    # [code: models/LSM.py#L414-L435]
    with no_gradient():
        speed_a = denoiser(x_t[flow_count:], time[flow_count:],
                           step[flow_count:], speech_cons)
        x_mid = x_t[flow_count:] + step[flow_count:] * speed_a
        speed_b = denoiser(x_mid, time[flow_count:] + step[flow_count:],
                           step[flow_count:], speech_cons)
        speed_target = (speed_a + speed_b) / 2
    # Prediction for one double step 2d from x_t  [eq. 6]
    # [code: models/LSM.py#L437-L442]
    speed_pred = denoiser(x_t[flow_count:], time[flow_count:],
                          2 * step[flow_count:], speech_cons)
    consistency_loss = mse(speed_pred, speed_target)
    # The two losses are summed without weights  [code: models/LSM.py#L452]
    return flow_loss + consistency_loss

Sampling with guidance §3.3 app. B

The code starts from Gaussian noise and runs Euler steps. At each step the model is evaluated with and without speech, and the outputs are combined with a guidance scale of 2. app. B LSM.py [code: models/LSM.py#L207]

Pseudocode
# Euler sampling with classifier-free guidance  [§3.3] [app. B]
# Input:  speech features; steps (8 in the reported results)  [tab. 2(f)]
# Output: latents (B, T, D), decoded by the RVQ decoders  [§3.1]

def sample(speech, steps=8, guidance_scale=2.0):
    # Start from Gaussian noise  [§3.3] [code: models/LSM.py#L292]
    x = sample_gaussian(latent_shape)
    # Uniform step; the same size is the shortcut d  [code: models/LSM.py#L297]
    dt = 1.0 / steps
    for index in range(steps):
        # Time at the start of this step  [code: models/LSM.py#L298]
        time = index * dt
        # Conditional and null-speech predictions
        # [code: models/LSM.py#L151-L209]
        cond = denoiser(x, time, dt, speech)
        uncond = denoiser(x, time, dt, null_speech)
        # Guided velocity  [app. B] [code: models/LSM.py#L207]
        velocity = uncond + guidance_scale * (cond - uncond)
        # Euler update  [§3.3] [code: models/LSM.py#L318]
        x = x + dt * velocity
    return x

Decoding to joints §3.1

Latent codes are decoded by the frozen RVQ decoders for each body region, and the decoded joints are the output. §3.1 shortcut_rvqvae_trainer.py

Hyperparameters

Values marked "paper" come from the text or appendix. Values marked "code" come from the official configuration or scripts and are not stated in the paper.

NameValueWhereNotes
Codebook size per body region1,024app. B
Code feature length128app. Bcode: --code-dim 128 in train_rvq.sh#L4
RVQ-VAE training iterations30,000 (paper)app. Bscript uses 300,000: train_rvq.sh#L4. Conflict, see Pitfalls
RVQ-VAE learning rate2e-4app. Bscript: --lr 2e-4
RVQ-VAE batch sizenot stated (paper)code: 256 (train_rvq.sh#L4)
RVQ stages (num_quantizers)not stated (paper)code: 6 (rvq_beatx_train.py#L260)
RVQ encoder width / depth / downsamplingnot stated (paper)code: 512 / 3 / 2 (train_rvq.sh#L4)
Latent dimension256app. Bcode: configs_new/shortcut_rvqvae_128.yaml#L85
Feed-forward size1024app. Bcode: configs_new/shortcut_rvqvae_128.yaml#L86
Cross-attention layers (speech fusion)3app. Bcode: models/denoiser.py#L43-L46
Spatial-temporal blocks8app. Bcode: configs_new/shortcut_rvqvae_128.yaml#L87
Attention headsnot stated (paper)code: 4 (configs_new/shortcut_rvqvae_128.yaml#L88)
Dropoutnot stated (paper)code: 0.1 (configs_new/shortcut_rvqvae_128.yaml#L89)
Latent sequence lengthnot stated (paper)code: 32 (configs_new/shortcut_rvqvae_128.yaml#L92)
Frames per training clipnot stated (paper)code: 128 at 30 fps (configs_new/shortcut_rvqvae_128.yaml#L25, #L43)
Context frames (seed)not stated (paper)code: 4 pre-frames, 8 seed vectors (configs_new/shortcut_rvqvae_128.yaml#L24, #L91)
Latent scalenot stated (paper)code: 5 (configs_new/shortcut_rvqvae_128.yaml#L27)
OptimiserAdamapp. Bcode: adam (configs_new/shortcut_rvqvae_128.yaml#L118)
Learning rate2e-4app. Bcode: lr_base: 2e-4 (configs_new/shortcut_rvqvae_128.yaml#L126)
Adam betasnot stated (paper)code: [0.5, 0.999] (configs_new/shortcut_rvqvae_128.yaml#L135)
Warm-upnot stated (paper)code: 50 steps from 5e-4 (configs_new/shortcut_rvqvae_128.yaml#L129, #L132)
Learning-rate decaynot stated (paper)code: x0.1 every 500 epochs (configs_new/shortcut_rvqvae_128.yaml#L128, #L130)
Gradient clippingnot stated (paper)code: norm 1.0 (configs_new/shortcut_rvqvae_128.yaml#L120)
Training epochs1,000app. Bcode: configs_new/shortcut_rvqvae_128.yaml#L119
Batch sizenot stated (paper)code: 128 (configs_new/shortcut_rvqvae_128.yaml#L36)
Time distributionBeta(2, 1.2)§3.3 tab. 2(c)Beta(2, 0.8) appears only as a commented-out alternative in the code
Flow-batch sharenot stated (paper)code: 3/4 with step size 0 (models/LSM.py#L356)
Step-size setnot stated (paper)code: 1/2 to 1/128, uniform (models/LSM.py#L352)
Null-speech rate, flow part0.1app. B (guidance dropout)code: models/LSM.py#L359
Null-speech rate, shortcut partnot stated (paper)code: 0.8 (models/LSM.py#L399)
Guidance scale at inference2app. Bcode: guidance_scale: 2 (configs_new/shortcut_rvqvae_128.yaml#L77)
Sampling steps8 (reported)tab. 2(f) app. Bcode config: n_steps: 2 (configs_new/shortcut_rvqvae_128.yaml#L78)
Audio sampling ratenot stated (paper)code: 16 kHz (configs_new/shortcut_rvqvae_128.yaml#L49)
Hardware1 x NVIDIA A100app. B

Results

Author-reported on BEAT2, with the EMAGE train/validation/test split. §4.1 The paper states the data as 60 hours from 25 speakers. §4.1 See Pitfalls for the speaker scope of the reported numbers.

Metrics §4.2 app. C:

  • FGD, Fréchet Gesture Distance, computed on latent features from a pretrained network app. C eq. 8:

\mathrm{FGD}(\mathbf{g}, \hat{\mathbf{g}}) = \|\mu_r - \mu_g\|^2 + \mathrm{Tr}\!\left(\Sigma_r + \Sigma_g - 2(\Sigma_r \Sigma_g)^{1/2}\right) \qquad \text{[eq. 8]}

  • Diversity: the average L1 distance between clips, with global translation removed. app. C eq. 9
  • Beat Constancy (BC): beat alignment between speech onsets and upper-body velocity minima, with a Gaussian of width \sigma. app. C eq. 10 The paper does not state \sigma. app. C The paper argues that BC should be compared with ground truth (0.703), not maximised. app. E
  • Efficiency: AIST (average inference time per sentence), recorded as AITS in the metric section. §4.2 tab. 1

\mathrm{L1\ div.} = \frac{1}{2N(N-1)} \sum_{t=1}^{N} \sum_{j=1}^{N} \left\| p_t^{i} - \hat{p}_t^{j} \right\|_1 \qquad \text{[eq. 9]}

\mathrm{BC} = \frac{1}{g} \sum_{b_g \in g} \exp\!\left(-\frac{\min_{b_a \in a} \|b_g - b_a\|^2}{2\sigma^2}\right) \qquad \text{[eq. 10]}

Eq. 9 is printed with indices i and j and a sum over t that does not match its normalisation. eq. 9 Use the official metric code where the two differ.

Main comparison tab. 1

Columns: FGD (\downarrow), BC (target: ground truth 0.703, \rightarrow), Diversity (\uparrow), MSE (\downarrow), AIST (\downarrow). "--" means the paper gives no value. Bold marks the best value in the paper. The caption says FGD and BC are multiplied by 10^{-1} and MSE by 10^{-7}, and does not say how to read the scaling. tab. 1

MethodFGDBCDiversityMSEAIST
Ground truth--0.70311.97----
HA2G12.320.6778.626--0.195
DisCo9.4170.6439.912--0.155
CaMN6.6440.67610.86--0.675
DiffSHEG7.1410.7438.219.5710.112
TalkShow6.2090.69513.477.7910.124
ProbTalk5.0400.77113.278.6140.231
EMAGE5.5120.77213.067.6800.174
MambaTalk5.3660.78113.057.6800.134
SynTalker4.6870.73612.43--2.942
GestureLSM4.0880.71413.24--0.039
GestureLSM (+ Face)4.2470.72913.761.0210.042

The text says GestureLSM achieves state-of-the-art results on all metrics and is closest to ground truth on BC §4.2. In the table, its BC (0.714) is the closest to 0.703, and its FGD is the lowest. Its diversity (13.24) is not the highest among the body-only rows: ProbTalk has 13.27 tab. 1. The face variant adds facial MSE (1.021). tab. 1

The paper reports a user study with 20 participants and 320 clips (80 per method, for GestureLSM, EMAGE, ProbTalk and DiffSHEG) on realness, synchrony and smoothness, scored 1 to 5. The mean opinion scores are plotted, not tabulated. §4.2 fig. 7

Ablations tab. 2

Each subtable reports FGD, BC and Diversity unless noted. Bold marks the best value in the paper, which is the proposed row in most cases.

(a) Module contribution. Removing spatial attention, temporal attention or positional encoding each hurts FGD. tab. 2(a)

VariantFGDBCDiv.
w/o spatial8.2320.76614.52
w/o temporal22.4120.45413.41
w/o position4.5230.65614.23
Ours4.0880.71413.24

(b) Architecture. tab. 2(b)

VariantFGDBCDiv.
Standard attention4.7620.73413.43
Ours + ST-Atten4.1320.73413.77
Only ST-Atten4.7670.74414.22
Bi-Mamba4.3230.74514.54
Ours4.0880.71413.24

(c) Time sampling. tab. 2(c)

VariantFGDBCDiv.
Uniform5.0510.72113.56
Logit-Normal4.4470.75513.72
Mode4.5320.73813.33
CosMap4.6210.74213.47
alpha=2, beta=1.24.0880.71413.24

(d) Generator model type (FGD, Div., AIST). tab. 2(d)

VariantFGDDiv.AIST
Diffusion (DDPM)4.13113.062.942
Autoregressive4.23213.030.153
Rectified flow4.72413.210.074
Masking4.63812.570.039
Ours4.08813.240.039

(e) Speed-up methods (FGD, Div., Tr-T, AIST). Tr-T is the training time in units of the base model's training. tab. 2(e)

VariantFGDDiv.Tr-TAIST
LCM4.44513.172.50.026
ReFlow^24.63813.1920.026
ReFlow^2 + Distill4.73113.2130.015
Ours4.08813.241.060.039
Ours + ReFlow^24.13213.712.120.018

(f) Sampling steps (FGD, BC, Div., AIST). tab. 2(f)

StepsFGDBCDiv.AIST
16.2350.64713.230.015
24.9880.68013.390.018
44.2620.70413.350.026
84.0880.71413.240.039
204.0400.73013.490.076

Additional ablations tab. 3

These are in the appendix. app. D tab. 3

(a) Speech features (FGD, BC, Div.). Cross-attention is best. tab. 3(a)

VariantFGDBCDiv.
w/o text4.3230.74313.17
WavLM audio encoder4.5670.70713.23
Concatenate + MLP4.6765.47911.67
Addition6.0126.23413.11
Cross-attention4.0880.71413.24

(b) Guidance scale (FGD, BC, Div.). tab. 3(b)

ScaleFGDBCDiv.
1.04.2150.74112.79
1.54.1410.73013.26
2.04.0880.71413.24
2.54.1240.71413.61
3.04.1570.70913.75

(c) Motion representation (FGD, BC, Div.). tab. 3(c)

VariantFGDBCDiv.
Raw 6D rotations (no quantisation)8.7270.61213.56
One VQ for the whole body6.3430.73413.42
One RVQ for the whole body5.2560.75513.35
Product quantiser4.4120.73713.41
Ours (per-region RVQ)4.0880.71413.24

(d) Attention order (FGD, BC, Div.). tab. 3(d)

OrderFGDBCDiv.
Spatial, then temporal4.0880.71413.24
Temporal, then spatial4.1130.72113.34

(e) Beta skew (FGD, BC, Div.). tab. 3(e)

alpha, betaFGDBCDiv.
2, 1.24.0880.71413.24
2, 1.04.1230.70413.44
2.2, 1.44.3620.75413.65
1.8, 1.44.3410.74313.73

Paper vs code

Official repository: andypinxinliu/GestureLSM, linked from the paper's project page. It is owned by the first author's account and has an MIT LICENSE (copyright Pinxin Liu). The clone is at commit f52ac2f. The code also has a MeanFlow variant and a diffusion variant that this card does not cover.

Discrepancies, each with both citations:

  • Speaker scope. The paper describes BEAT2 as 25 speakers §4.1. The shipped config trains on speaker id 2 only (training_speakers: [2], configs_new/shortcut_rvqvae_128.yaml#L55). The README says the reported statistics are the one-speaker results, and that the pretrained models use one speaker. README.md
  • Flow loss weighting. Eq. 4 is an unweighted mean squared error eq. 4. The code divides the flow MSE by each sample's t before averaging LSM.py. The MSE is one batch scalar here, so the weight is the mean of 1/t over the flow samples.
  • Spatial-first order. The paper and the block comment say spatial then temporal §3.2 transformer.py. The attention module defaults to spatial_first=False, which runs temporal attention first transformer.py [code: models/layers/transformer.py#L437-L443], and the block does not pass the flag transformer.py. Table 3(d) reports spatial-first as the better order tab. 3(d).
  • Positional encoding. The paper adds spatial and temporal positional encodings §3.2. The code applies rotary embeddings inside the attention transformer.py [code: models/denoiser.py#L118-L121].
  • Text encoder. The paper uses BERT for transcript semantics §3.1. The code uses a pretrained word-embedding table from weights/vocab.pkl modality_encoder.py, and the config names t_pre_encoder: fasttext shortcut_rvqvae_128.yaml.
  • RVQ training budget. The appendix states 30,000 iterations app. B. The script uses 300,000 with a learning-rate schedule at 200,000 train_rvq.sh.
  • Sampling steps. The reported results use 8 steps tab. 2(f). The shipped config uses n_steps: 2 [code: configs_new/shortcut_rvqvae_128.yaml#L78]. Nothing in the repository states which setting produced Table 1.
  • Guidance flag. The config sets do_classifier_free_guidance: False shortcut_rvqvae_128.yaml, but the model applies guidance whenever the scale exceeds 1 LSM.py LSM.py. The flag has no effect.
  • Consistency-stage schedule. The trainer passes train_consistency=True only after epoch 100 shortcut_rvqvae_trainer.py. The argument is never read in train_forward LSM.py, so the shortcut loss runs from epoch 0.
  • Null-speech rate. The code comment says 50/50 [code: models/LSM.py#L396-L397]. The call uses p = 0.8 for the null branch [code: models/LSM.py#L399].
  • Shortcut target. The second half-step is evaluated at t + d [code: models/LSM.py#L423-L425]. Eq. 6 writes t eq. 6.
  • Seed latents. The code also conditions the denoiser on 8 seed vectors taken from the first 4 latent frames of the clip [code: configs_new/shortcut_rvqvae_128.yaml#L91] [code: shortcut_rvqvae_trainer.py#L258]. The paper does not mention this input.

Not compared: the BC and diversity metric code. metric.py

Pitfalls

  • Speaker scope. Read the main text as "25 speakers" but the numbers as "speaker 2" until you have checked the training data and the split. Training with the shipped config uses speaker 2. Reproducing Table 1 needs the same scope. §4.1 shortcut_rvqvae_128.yaml [code: README.md#L135-L137]
  • Attention order and form. Eqs. 2 and 3 do not show the key transpose and give one positional term. Use standard scaled dot-product attention with rotary embeddings, as the code does, and test the order yourself, because the code's default order is temporal first. eq. 2 eq. 3 [code: models/layers/transformer.py#L437-L443]
  • Eq. 4 weighting. The paper's flow loss has no 1/t weight. The code has one. Pick one and state it. eq. 4 LSM.py
  • Target is not differentiated. The code computes the shortcut target under no-gradient LSM.py. The paper does not say this.
  • Two losses, no weights. The code sums the flow and consistency losses with weight 1 LSM.py. The paper gives no relative weight. The batch is split 3/4 flow and 1/4 consistency LSM.py. The paper gives neither split.
  • Few steps are cheap, but not free. The paper's step-count table shows FGD 6.235 at 1 step and 4.040 at 20 steps tab. 2(f). The 8-step setting in Table 1 is a trade-off, not a free choice.
  • Epoch-gate dead code. The epoch > 100 gate in the trainer has no effect shortcut_rvqvae_trainer.py LSM.py.
  • Units and naming. The paper calls the efficiency metric AIST in the table and AITS in the text, and reports it per sentence in one place and per frame in another tab. 1 §4.2. The FGD and BC scaling in the caption is not explained tab. 1.
  • Beat Constancy. The paper says higher BC is better, and then argues that it should match ground truth (0.703) §4.2 app. E. The Table 1 BC column has its target arrow pointing to ground truth.
  • Missing details. Not stated in the paper: \sigma in BC, batch size, step-size set, RVQ stage count, encoder shape, context-frame handling and the optimiser's betas and warm-up. The code supplies values for all of them (see Hyperparameters), but these are not paper values.
  • Long clips. The code splits long sequences into windows with overlapping pre-frames at test time shortcut_rvqvae_trainer.py. The paper does not describe this.
  • Other results. The README's results table reports different numbers on another scale (for example a shortcut at 20 steps with FGD 0.4040). Do not compare it with Table 1. README.md
  • Speed claim. The 0.039 s figure is per sentence in the table and per frame in the text. Measure your own setup before you rely on it. tab. 1 §4.2

Lineage

  • Builds on: flow matching and rectified flow §3.3 (cited there as lipman2022flow and liu2022flowstraightfastlearning), shortcut models §3.3 (cited as shortcutmodels), and residual vector quantisation §3.1 (cited as rvq).
  • Data split from EMAGE §4.1. Reset strategy for the codebook follows Contextual Gesture app. B.
  • Compared against: HA2G, DisCo, CaMN, DiffSHEG, TalkShow, ProbTalk, EMAGE, MambaTalk and SynTalker tab. 1.
  • Superseded by: not known from this wiki.

Figures

The paper's figures are described above and cited in place. No figure is reproduced here. fig. 1 shows a teaser of the method. fig. 2 plots FGD against inference time. fig. 3 shows the overall pipeline. fig. 4 shows the shows the shortcut self-consistency idea eq. 6. fig. 5 compares time-sampling schedules. fig. 6 shows qualitative comparisons. fig. 7 is the user study. fig. 8 shows an avatar application. fig. 9 tracks training dynamics. §3 §4 app. E

Source and license

Adapted from “GestureLSM: Latent Shortcut based Co-Speech Gesture Generation with Spatial-Temporal Modeling” by Pinxin Liu, Luchuan Song, Junhua Huang, Haiyang Liu, Junfan Zhu, Chenliang Xu (arXiv:2501.18898), used under CC BY 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors. Code citations refer to https://github.com/andypinxinliu/GestureLSM at commit f52ac2f53dd1 (MIT). Any quoted code is shown under that license.