Skip to content

pnnx silently changes circular padding to reflect or constant padding #7061

Open

Description

@ktz03

error log | 日志或报错信息 | ログ

At bbaca40c35ce39f635c947e564710dae42fba142, pnnx converts torch.stft(..., center=True, pad_mode="circular") to a loadable Spectrogram layer with 6=2 (reflect). torchaudio.functional.spectrogram has the same behavior. F.pad(..., mode="circular") becomes Padding without a mode parameter, so it uses constant padding.

The generated ncnn models return numerically different results without an unsupported-padding diagnostic. For the STFT reproduction below, the maximum absolute error is 1.2021422; the result instead matches the reflect-padding reference within 3.95e-6. A (2, 3, 128) torchaudio power spectrogram gives a maximum absolute error of 30.0352. A separate F.pad(x, (3, 4), mode="circular") model with input shape (2, 128) gives 0.76822.

model | 模型 | モデル

This is a TorchScript conversion issue. The following script generates the original model and checks the converted result:

import subprocess
import torch

class Model(torch.nn.Module):
    def __init__(self, mode):
        super().__init__()
        self.mode = mode

    def forward(self, x):
        return torch.view_as_real(torch.stft(
            x, n_fft=32, hop_length=8, win_length=32,
            window=torch.hann_window(32), center=True,
            pad_mode=self.mode, return_complex=True))

torch.manual_seed(0)
x = torch.rand(128)
model = Model("circular").eval()
torch.jit.trace(model, x).save("circular_stft.pt")
subprocess.run(["pnnx", "circular_stft.pt", "inputshape=[128]", "fp16=0"], check=True)

import circular_stft_ncnn
actual = circular_stft_ncnn.test_inference()
print("circular error:", (model(x) - actual).abs().max().item())
print("reflect error:", (Model("reflect")(x) - actual).abs().max().item())

how to reproduce | 复现步骤 | 再現方法

  1. Build pnnx and the ncnn Python bindings from the commit above.
  2. Run the script with pnnx on PATH. I reproduced this on Windows x64, MSVC 19.44, Python 3.14.3, PyTorch 2.11.0+cpu and torchaudio 2.11.0, using CPU inference and fp16=0.
  3. Inspect the generated circular_stft.ncnn.param: it contains Spectrogram ... 5=1 6=2 even though the .pnnx.param retains pad_mode=circular.

The runtime currently supports constant, replicate and reflect padding. Unsupported circular padding should stay unconverted with a diagnostic, rather than become a different supported mode. The normal constant/replicate/reflect cases pass numerical controls. center=False also passes because STFT does not use the padding mode in that case.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions