[BUG] OneCycle applies the minimum momentum to the first Adam update
Maintainer thường phản hồi trong vòng 2 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
- 78/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Lĩnh vực
- machine-learning
Hướng nghiên cứu
Bắt đầu với deepspeed/runtime/lr_schedules.py, đặc biệt là OneCycle._initialize_momentum() và bài kiểm tra momentum khởi đầu được nhắc đến trong issue. Dùng phép tái hiện trên CPU với float64 và hai lần cập nhật Adam để kiểm tra rằng một chu kỳ mới áp dụng momentum tối đa ở lần cập nhật đầu tiên và khớp với tham chiếu độc lập; xác nhận rằng việc khởi tạo lại sau khi tiếp tục giữ nguyên các thiết lập optimizer đã được khôi phục.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Description
On DeepSpeed master 8d4f29c75f4a4b30d4db00a94b4aebfdff5107f3, constructing OneCycle with momentum cycling enabled sets the optimizer's initial beta1 to cycle_min_mom, while scheduler.get_mom() reports cycle_max_mom. The first actual optimizer update therefore consumes a different momentum from the inverse LR/momentum schedule.
This changes Adam's accumulated first moment. Bias correction can hide the problem in the first parameter update, but the second update diverges from the intended schedule. This is a training-correctness issue, not a security issue.
Reproduction
Run the following with DeepSpeed imported from the revision above. It uses real forward/backward and optimizer updates; no mocks or GPU are required. Beta2 is explicitly 0.99 to isolate this issue from the existing beta2 reports.
# SPDX-License-Identifier: Apache-2.0
# DeepSpeed Team
import torch
from deepspeed.runtime.lr_schedules import OneCycle
actual = torch.nn.Linear(1, 1, bias=False).double()
reference = torch.nn.Linear(1, 1, bias=False).double()
with torch.no_grad():
actual.weight.fill_(1.0)
reference.weight.fill_(1.0)
optimizer = torch.optim.Adam(actual.parameters(), lr=0.1, betas=(0.9, 0.99), foreach=False)
reference_optimizer = torch.optim.Adam(reference.parameters(), lr=0.1, betas=(0.9, 0.99), foreach=False)
scheduler = OneCycle(optimizer, cycle_min_lr=0.1, cycle_max_lr=0.2,
cycle_first_step_size=4, cycle_second_step_size=4,
cycle_min_mom=0.8, cycle_max_mom=0.9)
print('optimizer initial beta1:', optimizer.param_groups[0]['betas'][0])
print('scheduler initial beta1:', scheduler.get_mom()[0][0])
inputs = torch.ones(1, 1, dtype=torch.float64)
for lr, beta1 in [(0.1, 0.9), (0.125, 0.875)]:
reference_optimizer.param_groups[0]['lr'] = lr
reference_optimizer.param_groups[0]['betas'] = (beta1, 0.99)
for model, optim in [(actual, optimizer), (reference, reference_optimizer)]:
optim.zero_grad()
loss = 0.5 * model(inputs).square().sum()
loss.backward()
optim.step()
scheduler.step()
print('actual weight:', actual.weight.item())
print('reference weight:', reference.weight.item())
torch.testing.assert_close(actual.weight, reference.weight, rtol=0, atol=0)
print('PASS: both Adam updates match the inverse-momentum reference')
Observed output:
optimizer initial beta1: 0.8
scheduler initial beta1: 0.9
actual weight: 0.7387770530174719
reference weight: 0.7878449067299509
AssertionError: Tensor-likes are not equal!
Expected behavior
A fresh inverse cycle must apply minimum LR and maximum momentum to the first optimizer update, consistently with get_mom(). The independent two-update reference should match. Resumed construction must not overwrite restored optimizer settings.
Root cause
OneCycle._initialize_momentum() writes self.min_moms into the optimizer when last_batch_iteration == -1. The cyclic momentum calculation starts at self.max_moms. The engine invokes the optimizer before stepping the scheduler, so the discrepancy affects training before the first scheduler step.
The parameter docstring incorrectly describes the lower bound as initial momentum; this contradicts the inverse-cycling description and the existing starting-momentum test.
Environment and validation
- Linux x86_64, Python 3.11.15, PyTorch 2.12.1+cu126; DeepSpeed source reports 0.19.9.
- Minimal reproduction: CPU, float64, PyTorch Adam.
- Also reproduced through
deepspeed.initialize()/backward()/step()on one RTX 3090, CUDA runtime 12.6, driver 580.178.04, FP32, ZeRO stage 0, no offload. - Real-engine two-update weight error before the fix: 0.04906785488128662. After initializing from the maximum momentum: 5.960464477539063e-08 versus the FP32 reference (rtol=1e-6, atol=1e-7). The CPU float64 reproduction matches exactly after the fix.
- These are short numerical-correctness checks, not full-model convergence or throughput benchmarks.
Environment report from the validated checkout:
Recorded ds_report output (local installation paths redacted)
--------------------------------------------------
DeepSpeed C++/CUDA extension op report
--------------------------------------------------
NOTE: Ops not installed will be just-in-time (JIT) compiled at
runtime if needed. Op compatibility means that your system
meet the required dependencies to JIT install the op.
--------------------------------------------------
JIT compiled ops requires ninja
ninja .................. [92m[OKAY][0m
--------------------------------------------------
op name ................ installed .. compatible
--------------------------------------------------
[93m [WARNING] [0m async_io requires the dev libaio .so object and headers but these were not found.
[93m [WARNING] [0m async_io: please install the libaio-dev package with apt
[93m [WARNING] [0m If libaio is already installed (perhaps from source), try setting the CFLAGS and LDFLAGS environment variables to where it can be found.
async_io ............... [93m[NO][0m ....... [93m[NO][0m
fused_adam ............. [93m[NO][0m ....... [92m[OKAY][0m
cpu_adam ............... [93m[NO][0m ....... [92m[OKAY][0m
cpu_adagrad ............ [93m[NO][0m ....... [92m[OKAY][0m
cpu_lion ............... [93m[NO][0m ....... [92m[OKAY][0m
pin_memory ............. [93m[NO][0m ....... [92m[OKAY][0m
dc ..................... [93m[NO][0m ....... [92m[OKAY][0m
[93m [WARNING] [0m Unable to locate CUTLASS. Install nvidia-cutlass, clone CUTLASS next to DeepSpeed, or set CUTLASS_PATH to the CUTLASS checkout.
evoformer_attn ......... [93m[NO][0m ....... [93m[NO][0m
fp_quantizer ........... [93m[NO][0m ....... [92m[OKAY][0m
fused_lamb ............. [93m[NO][0m ....... [92m[OKAY][0m
fused_lion ............. [93m[NO][0m ....... [92m[OKAY][0m
[93m [WARNING] [0m gds requires the dev libaio .so object and headers but these were not found.
[93m [WARNING] [0m gds: please install the libaio-dev package with apt
[93m [WARNING] [0m If libaio is already installed (perhaps from source), try setting the CFLAGS and LDFLAGS environment variables to where it can be found.
gds .................... [93m[NO][0m ....... [93m[NO][0m
transformer_inference .. [93m[NO][0m ....... [92m[OKAY][0m
inference_core_ops ..... [93m[NO][0m ....... [92m[OKAY][0m
cutlass_ops ............ [93m[NO][0m ....... [92m[OKAY][0m
utils .................. [93m[NO][0m ....... [92m[OKAY][0m
transformer ............ [93m[NO][0m ....... [92m[OKAY][0m
quantizer .............. [93m[NO][0m ....... [92m[OKAY][0m
spatial_inference ...... [93m[NO][0m ....... [92m[OKAY][0m
ragged_device_ops ...... [93m[NO][0m ....... [92m[OKAY][0m
ragged_ops ............. [93m[NO][0m ....... [92m[OKAY][0m
random_ltd ............. [93m[NO][0m ....... [92m[OKAY][0m
stochastic_transformer . [93m[NO][0m ....... [92m[OKAY][0m
--------------------------------------------------
DeepSpeed general environment info:
torch install path ............... [local path redacted]
torch version .................... 2.12.1+cu126
deepspeed install path ........... [local path redacted]
deepspeed info ................... 0.19.9, [none], [none]
torch cuda version ............... 12.6
torch hip version ................ None
nvcc version ..................... 12.1
deepspeed wheel compiled w. ...... torch 0.0, cuda 0.0
shared memory (/dev/shm) size .... 125.77 GB
Related work / duplicate check
Live issue/open-PR searches found no initial-beta1-endpoint fix. #8750, #8751 and #8495 concern preservation of beta2; #8589 concerns post-cycle momentum decay; #8472 concerns CLI forwarding; #8528 concerns tensor LR aliasing; #8753 concerns initial get_last_lr(). Their changes do not correct the initial beta1 endpoint. This report does not request those unrelated fixes.
AI assistance was used to investigate and prepare this report. The report and proposed fix were reviewed before submission.
- Ngôn ngữ chính
- Python
- Star
- 43.3k
- Fork
- 5.1k
- Merge trung bình
- 4 ngày 7 giờ
- Pull request đã merge (30 ngày)
- 66
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không 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 deepspeedai/DeepSpeed
-
[BUG] Universal checkpoint resume puts CPU `step` into fused/capturable optimizer stateCó thể đã có người làm @ArjunPakhan đã nhận 9 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 74/100
deepspeedai/DeepSpeed#8884 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
init_inference rejects dtype=torch.int8 on every acceleratorCó thể làm lại được Pull request cho issue này đã bị đóng mà không được merge. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
deepspeedai/DeepSpeed#8577 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
[BUG] AutoTP checkpoint load raises AttributeError on a model containing nn.InstanceNorm1dCó thể đã có người làm @vineethsaivs đã nhận 47 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
deepspeedai/DeepSpeed#8514 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
[BUG] Python checkpoint writers fail to reload full ZeRO-3 state with default torch.loadCó thể đã có người làm @ai-yang đã nhận 48 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
deepspeedai/DeepSpeed#8500 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
[BUG] set_norm_for_param_grad_in_gpu's grad_accum fallback is dead in both accumulation modesCó thể đã có người làm @LOGO127 đã nhận 57 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
deepspeedai/DeepSpeed#8371 ·
Maintainer thường phản hồi trong vòng 2 ngày
Tất cả issue của deepspeedai/DeepSpeed
Issue tương tự
-
[Bug]: Responses API 500s on assistant message with empty content listCó thể đã có người làm @shadowmodder đã nhận hôm nay. Đang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 66/100
vllm-project/vllm#64940 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
limits
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Keybind quest outdatedĐang mởStatus: Triage Type: Quest
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 66/100
GTNewHorizons/GT-New-Horizons-Modpack#27490 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
LLM.save() discards the model's active prompt styleCó thể đã có người làm @remote-controlled-man đã 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
Lightning-AI/litgpt#2378 ·
Maintainer thường phản hồi trong vòng 23 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
Maintainer thường phản hồi trong vòng 1 ngày