[BUG] mts.sparsify(mode="sparsegpt") applies only the mask, not the SparseGPT weight update

Đang mở
#3,262 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
72/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
python, pytorch
Lĩnh vực
machine-learning

Hướng nghiên cứu

Read modelopt/torch/sparsity/weight_sparsity/sparsegpt.py and trace how create_sgpt_mask() passes its result through SparseGPTSearcher._compute_mask and BaseSparseSearcher.run_search() in weight_sparsity/sparsification.py. Reproduce the CPU case from the issue, then check whether the SparseGPT weight update reaches the module while preserving the same 2:4 mask. Done means the kept weights are updated and output MSE is below the mask only result; add and run a regression test for that behavior.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Describe the bug

The docs say the "sparsegpt" mode updates the weights. mts.sparsify describes it as "2:4 weight sparsity with SparseGPT weight updates" (modelopt/torch/sparsity/sparsification.py), and weight_sparsity/sparsification.py says the weights are updated using a Hessian approximation.

In the code the update is computed and then dropped:

  • prepare() in weight_sparsity/sparsegpt.py clones the weight.
  • create_sgpt_mask() runs the SparseGPT/OBS update on that clone, then returns only mask = weight != 0.
  • BaseSparseSearcher.run_search() only calls module.set_mask(...).

So the kept weights keep their dense values. The result is the dense weight times the SparseGPT mask.

Steps to reproduce

Main at 86bd9b78425a23a45b329c7c9b86ea772d7a9e77, CPU.

import torch
import torch.nn as nn
import modelopt.torch.sparsity as mts

torch.manual_seed(0)
model = nn.Sequential(nn.Linear(64, 32, bias=False))
w_dense = model[0].weight.detach().clone()
x = torch.randn(512, 8) @ torch.randn(8, 64) + 0.05 * torch.randn(512, 64)  # correlated inputs
y_dense = x @ w_dense.t()

model = mts.sparsify(model, "sparsegpt", config={"forward_loop": lambda m: m(x), "device": "cpu"})
with torch.no_grad():
    y = model(x)
w = model[0].weight.detach()
mask = w != 0

print("kept weights equal to dense weights:", torch.equal(w[mask], w_dense[mask]))
print("output MSE, sparsegpt model         :", ((y - y_dense) ** 2).mean().item())
print("output MSE, dense weights * same mask:", ((x @ (w_dense * mask).t() - y_dense) ** 2).mean().item())

Actual:

kept weights equal to dense weights: True
output MSE, sparsegpt model         : 0.24907712638378143
output MSE, dense weights * same mask: 0.24907712638378143

Expected: the kept weights change and the output error drops below the mask-only error. With the update written back, the same script gives False, 0.0481 and 0.2491 (rounded). The mask is the same and the 2:4 pattern still holds. bfloat16 behaves the same way: 0.2537 on main, 0.0491 with the update.

Proposed fix

SparseGPTSearcher._compute_mask copies the updated weight into the module's raw weight parameter (not the masked module.weight) before returning the same mask. create_sgpt_mask keeps its signature.

Is the mask-only behavior intended? If it is, the docs above should say so, and I can send a docs fix instead. If not, I have the fix and a regression test ready and can open a PR after a maintainer confirms.

Ngôn ngữ chính
Python
Star
5.5k
Fork
800
Merge trung bình
3 ngày 6 giờ
Pull request đã merge (30 ngày)
267

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. 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.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của NVIDIA/Model-Optimizer

Tất cả issue của NVIDIA/Model-Optimizer

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.