Skip to content

feat: Gradient clipping and accumulation - #660

Open
sjohn4 wants to merge 2 commits into
mainfrom
sjohn/grad_norm_accumulation
Open

feat: Gradient clipping and accumulation#660
sjohn4 wants to merge 2 commits into
mainfrom
sjohn/grad_norm_accumulation

Conversation

@sjohn4

@sjohn4 sjohn4 commented Apr 14, 2025

Copy link
Copy Markdown
Collaborator

Added gradient clipping and accumulation.

@sjohn4
sjohn4 requested a review from MaxiBoether April 14, 2025 16:16
@github-actions

Copy link
Copy Markdown

Line Coverage: -% ( % to main)
Branch Coverage: -% ( % to main)

@sjohn4
sjohn4 force-pushed the sjohn/grad_norm_accumulation branch 2 times, most recently from ceaf307 to f1d1c58 Compare April 17, 2025 17:00
@codecov

codecov Bot commented Apr 17, 2025

Copy link
Copy Markdown

Codecov Report

Attention: Patch coverage is 96.55172% with 1 line in your changes missing coverage. Please review.

Project coverage is 85.72%. Comparing base (c961257) to head (c71673f).

Files with missing lines Patch % Lines
...trainer_server/internal/trainer/pytorch_trainer.py 95.83% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #660      +/-   ##
==========================================
+ Coverage   85.58%   85.72%   +0.14%     
==========================================
  Files         258      258              
  Lines       11378    11392      +14     
==========================================
+ Hits         9738     9766      +28     
+ Misses       1640     1626      -14     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@MaxiBoether MaxiBoether left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks John, a couple of small comments

Comment on lines +168 to +179
@field_validator("gradient_accumulation_steps")
@classmethod
def validate_accumulation_steps(cls, value: int) -> int:
if value < 1:
raise ValueError("Invalid value for gradient_accumulation_steps, must be greater than 0.")
return value

@field_validator("max_grad_norm")
@classmethod
def validate_max_grad_norm(cls, value: float) -> float:
if value is not None and value <= 0:
raise ValueError("Invalid value for max_grad_norm, must be greater than 0.")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be checked via the min/max value of Field, not via extra validators

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

)
max_grad_norm: float | None = Field(
default=None,
description="Clips the gradients normed over this value, if its 0 it will not be used.",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean if it's None nothing will be clipped?

@sjohn4 sjohn4 Apr 23, 2025

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it is None then nothing is clipped, we skip the function in the pytorch trainer, I guess we can also just skip when it is 0 since it never makes sense to clip to 0.

Comment thread modyn/protos/trainer_server.proto Outdated
bool enable_accurate_gpu_measurements = 25;
int64 record_loss_every = 26;
bool drop_last_batch = 27;
float grad_norm = 28;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we rename this to max_grad_norm?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and shouldn't it be optional float? since it's optional in the config schema?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment on lines +459 to +466
# Instead of checking the logged "num_batches_trained" (which counts mini-batches),
# we compare the final model parameters to ensure they are equivalent.
final_params_accum = clone_params(trainer_accum._model.model)
final_params_single = clone_params(trainer_single._model.model)

for name in init_params.keys():
assert torch.allclose(final_params_accum[name], final_params_single[name], atol=1e-5), f"Mismatch in {name}"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I appreciate this test, but can we somehow check the actual accumulation and not the side effect (same parameters)? e.g., can we mock the optimizer and model to check how often this/with which data they were called? we can keep this test and add another test, but right now we don't actually test the accumulation

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made a new test, I think it does what you wanted.

Comment on lines +88 to +89
self._max_grad_norm = training_info.max_grad_norm
self.gradient_accumulation_steps = training_info.gradient_accumulation_steps

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if you make max grad norm private then also gradient accumulation steps should be private. Can you move those to lines to line ~ 121 (where we set a lot of internal variables)?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@MaxiBoether MaxiBoether changed the title Gradient clipping and accumulation feat: Gradient clipping and accumulation Apr 23, 2025
@sjohn4
sjohn4 force-pushed the sjohn/grad_norm_accumulation branch from fe01aa7 to efdf0b9 Compare April 24, 2025 06:56
@sjohn4
sjohn4 requested a review from MaxiBoether April 25, 2025 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants