🐛 [Bug] torch.fmod returns a tiny value with the wrong sign when the float quotient rounds up
Maintainer thường phản hồi trong vòng 3 ngày
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 70/100
Hướng nghiên cứu
Bắt đầu từ impl.elementwise.fmod và hàm hỗ trợ trunc_div trong py/torch_tensorrt/dynamo/conversion/impl/elementwise/ops.py, rồi kiểm tra cách thương số dấu phẩy động được làm tròn xuống trước khi tính phần dư. Chạy script tái hiện từ issue trên máy có CUDA và so sánh với torch.fmod cho 4.2 / 1.4 và trường hợp 0.1 bị bọc lại. Hoàn thành khi kết quả fmod với số thực khớp PyTorch về dấu và giá trị, đồng thời hành vi với số nguyên không đổi.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Bug Description
torch.fmod(a, b) on floating point tensors returns a tiny value with the wrong sign when a / b rounds up to a whole number. In float32, torch.fmod(4.2, 1.4) is 1.3999999 in PyTorch and -1.19e-07 in Torch-TensorRT. The result of fmod always has the sign of a, so a negative result for a positive a is never right. It shows up when wrapping values by a period: fmod(x, 0.1) for x = 0.1, 0.2, ..., 10.0 differs from PyTorch for 43 of the 100 values.
impl.elementwise.fmod in py/torch_tensorrt/dynamo/conversion/impl/elementwise/ops.py computes input - trunc_div(input, other) * other, and trunc_div takes FLOOR_DIV of |input| and |other|. For floats, the division is rounded before it's floored. In float32, 4.2 / 1.4 is 2.99999991, which rounds to 3.0, so the quotient comes out as 3 instead of 2 and input - 3 * other is just below zero. PyTorch computes fmod exactly and gets 2.
torch.remainder (%) gives the right result for these inputs.
To Reproduce
import torch
import torch_tensorrt
class Fmod(torch.nn.Module):
def forward(self, a, b):
return torch.fmod(a, b)
def trt(model, *args):
return torch_tensorrt.compile(model.eval().cuda(), ir="dynamo", inputs=list(args), min_block_size=1)(*args)
a = torch.tensor([4.2, -4.2, 0.7, 5.0], device="cuda")
b = torch.tensor([1.4, 1.4, 0.1, 3.0], device="cuda")
print(Fmod()(a, b).tolist())
print(trt(Fmod(), a, b).tolist())
# Wrapping multiples of 0.1 by 0.1
x = torch.arange(1, 101, device="cuda") * 0.1
period = torch.full_like(x, 0.1)
expected, got = Fmod()(x, period), trt(Fmod(), x, period)
print((got - expected).abs().gt(1e-3).sum().item(), "of", x.numel(), "differ")
Output:
[1.3999998569488525, -1.3999998569488525, 0.09999997913837433, 2.0]
[-1.1920928955078125e-07, 1.1920928955078125e-07, -2.2351741790771484e-08, 2.0]
43 of 100 differ
Expected behavior
The same results as PyTorch, which always have the sign of a.
Environment
- Torch-TensorRT Version: 2.14.0 (pip).
fmodandtrunc_divare the same on main. - PyTorch Version: 2.14.1+cu130
- CPU Architecture: x86_64
- OS: Ubuntu 26.04 (WSL2)
- How you installed PyTorch: pip
- Python version: 3.12
- CUDA version: 13.0 (TensorRT 11.1.0.106)
- GPU models and configuration: NVIDIA GeForce RTX 5060 Ti, driver 596.49
Additional context
I found this with torchparity, a tool I'm writing that runs PyTorch ops through converters and compares the results with eager PyTorch. I have a fix with tests and can open a PR. When the result has the sign opposite to input, it adds |other| back with the sign of input. Integer inputs are unchanged.
#4786 changes trunc_div for large integers and doesn't cover this.
- Ngôn ngữ chính
- Python
- Star
- 3k
- Fork
- 421
- Merge trung bình
- 4 ngày 7 giờ
- Pull request đã merge (30 ngày)
- 62
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của pytorch/TensorRT
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
Maintainer thường phản hồi trong vòng 3 ngày
-
Removing ptq.hĐang mởStory: Build & Install & Packaging
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 65/100
Maintainer thường phản hồi trong vòng 3 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 22/100
Maintainer thường phản hồi trong vòng 3 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 18/100
Maintainer thường phản hồi trong vòng 3 ngày
-
Độ khó 3/5 Nửa ngày Mức phù hợp với người mới 65/100
Maintainer thường phản hồi trong vòng 3 ngày
Tất cả issue của pytorch/TensorRT
Issue tương tự
-
add entry to blockĐang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 65/100
StevenBlack/hosts#3299 ·
-
`garak --report` overwrites the input report when its name has no ".report"Có thể đã có người làm @0z5a đã nhận hôm nay. Đang mởneeds-triage
Độ khó 2/5 Nửa ngày Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 2 ngày
-
plot_graph crashes when a mesh node has no m2m edgeCó thể đã có người làm @tygvi đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
mllam/neural-lam#883 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
future-agi/future-agi#4092 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
transcript analytics: a text whose only protected spans the prose pass redacts is withheld wholeĐang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 82/100
WingedGuardian/GENesis-AGI#4641 ·
Maintainer thường phản hồi trong vòng 1 ngày