Skip to content

Commit

Permalink
Enable more Ruff lints & fix issues (#2419)
Browse files Browse the repository at this point in the history
* Remove antiquated flake8 and isort configuration

* Bump to Ruff 0.2.1

* Explain ruff options

* Autofix Ruff B010 (static `setattr`)

* Autofix Ruff B009 (static `getattr`)

* Enable Ruff UP (not UP007); auto-fix

* Fix remaining Ruff UP complaints

* Fix a couple more format calls
  • Loading branch information
akx authored Feb 14, 2024
1 parent aba3b8c commit 13e79cc
Show file tree
Hide file tree
Showing 46 changed files with 121 additions and 157 deletions.
2 changes: 1 addition & 1 deletion docs/source/usage_guides/deepspeed.md
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ ZeRO Stage-3 has 2 options:
Below is the snippet from `examples/by_feature/deepspeed_with_config_support.py` showing this:
```python
success = model.save_checkpoint(PATH, ckpt_id, checkpoint_state_dict)
status_msg = "checkpointing: PATH={}, ckpt_id={}".format(PATH, ckpt_id)
status_msg = f"checkpointing: PATH={PATH}, ckpt_id={ckpt_id}"
if success:
logging.info(f"Success {status_msg}")
else:
Expand Down
1 change: 0 additions & 1 deletion examples/by_feature/checkpointing.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding=utf-8
# Copyright 2021 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
1 change: 0 additions & 1 deletion examples/by_feature/cross_validation.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding=utf-8
# Copyright 2022 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
1 change: 0 additions & 1 deletion examples/by_feature/deepspeed_with_config_support.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/env python
# coding=utf-8
# Copyright 2022 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
1 change: 0 additions & 1 deletion examples/by_feature/early_stopping.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding=utf-8
# Copyright 2021 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
19 changes: 8 additions & 11 deletions examples/by_feature/fsdp_with_peak_mem_tracking.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding=utf-8
# Copyright 2021 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -334,13 +333,11 @@ def collate_fn(examples):
accelerator.save_state(output_dir)
# New Code #
# Printing the GPU memory usage details such as allocated memory, peak memory, and total memory usage
accelerator.print("Memory before entering the train : {}".format(b2mb(tracemalloc.begin)))
accelerator.print("Memory consumed at the end of the train (end-begin): {}".format(tracemalloc.used))
accelerator.print("Peak Memory consumed during the train (max-begin): {}".format(tracemalloc.peaked))
accelerator.print(f"Memory before entering the train : {b2mb(tracemalloc.begin)}")
accelerator.print(f"Memory consumed at the end of the train (end-begin): {tracemalloc.used}")
accelerator.print(f"Peak Memory consumed during the train (max-begin): {tracemalloc.peaked}")
accelerator.print(
"Total Peak Memory consumed during the train (max): {}".format(
tracemalloc.peaked + b2mb(tracemalloc.begin)
)
f"Total Peak Memory consumed during the train (max): {tracemalloc.peaked + b2mb(tracemalloc.begin)}"
)
# Logging the peak memory usage of the GPU to the tracker
if args.with_tracking:
Expand Down Expand Up @@ -387,11 +384,11 @@ def collate_fn(examples):
accelerator.save_state(output_dir)
# New Code #
# Printing the GPU memory usage details such as allocated memory, peak memory, and total memory usage
accelerator.print("Memory before entering the eval : {}".format(b2mb(tracemalloc.begin)))
accelerator.print("Memory consumed at the end of the eval (end-begin): {}".format(tracemalloc.used))
accelerator.print("Peak Memory consumed during the eval (max-begin): {}".format(tracemalloc.peaked))
accelerator.print(f"Memory before entering the eval : {b2mb(tracemalloc.begin)}")
accelerator.print(f"Memory consumed at the end of the eval (end-begin): {tracemalloc.used}")
accelerator.print(f"Peak Memory consumed during the eval (max-begin): {tracemalloc.peaked}")
accelerator.print(
"Total Peak Memory consumed during the eval (max): {}".format(tracemalloc.peaked + b2mb(tracemalloc.begin))
f"Total Peak Memory consumed during the eval (max): {tracemalloc.peaked + b2mb(tracemalloc.begin)}"
)
# Logging the peak memory usage of the GPU to the tracker
if args.with_tracking:
Expand Down
1 change: 0 additions & 1 deletion examples/by_feature/gradient_accumulation.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding=utf-8
# Copyright 2021 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
1 change: 0 additions & 1 deletion examples/by_feature/local_sgd.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding=utf-8
# Copyright 2023 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
1 change: 0 additions & 1 deletion examples/by_feature/megatron_lm_gpt_pretraining.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#!/usr/bin/env python
# coding=utf-8
# Copyright 2021 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
1 change: 0 additions & 1 deletion examples/by_feature/multi_process_metrics.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding=utf-8
# Copyright 2022 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
1 change: 0 additions & 1 deletion examples/by_feature/tracking.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding=utf-8
# Copyright 2021 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
1 change: 0 additions & 1 deletion examples/complete_cv_example.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding=utf-8
# Copyright 2021 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
1 change: 0 additions & 1 deletion examples/complete_nlp_example.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding=utf-8
# Copyright 2021 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
1 change: 0 additions & 1 deletion examples/cv_example.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding=utf-8
# Copyright 2021 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
1 change: 0 additions & 1 deletion examples/inference/bert.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding=utf-8
# Copyright 2024 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
1 change: 0 additions & 1 deletion examples/inference/gpt2.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding=utf-8
# Copyright 2024 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
1 change: 0 additions & 1 deletion examples/inference/llama.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding=utf-8
# Copyright 2024 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
1 change: 0 additions & 1 deletion examples/inference/t5.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding=utf-8
# Copyright 2024 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
1 change: 0 additions & 1 deletion examples/nlp_example.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding=utf-8
# Copyright 2021 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
31 changes: 24 additions & 7 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,32 @@
[tool.ruff]
# Never enforce `E501` (line length violations).
ignore = ["E501", "E741", "W605"]
select = ["E", "F", "I", "W"]
line-length = 119
target-version = "py38"

# Ignore import violations in all `__init__.py` files.
[tool.ruff.per-file-ignores]
"__init__.py" = ["E402", "F401", "F403", "F811"]
[tool.ruff.lint]
ignore-init-module-imports = true
extend-select = [
"B009", # static getattr
"B010", # static setattr
"E", # PEP8 errors
"F", # PEP8 formatting
"I", # Import sorting
"W", # PEP8 warnings
"UP", # Pyupgrade
]
ignore = [
"E501", # Line length (handled by ruff-format)
"E741", # Ambiguous variable name
"W605", # Invalid escape sequence
"UP007", # X | Y type annotations
]

[tool.ruff.lint.per-file-ignores]
"__init__.py" = [
"F401", # Ignore seemingly unused imports (they're meant for re-export)
]
"manim_animations/*" = ["ALL"]

[tool.ruff.isort]
[tool.ruff.lint.isort]
lines-after-imports = 2
known-first-party = ["accelerate"]

Expand Down
14 changes: 0 additions & 14 deletions setup.cfg

This file was deleted.

4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
extras["quality"] = [
"black ~= 23.1", # hf-doc-builder has a hidden dependency on `black`
"hf-doc-builder >= 0.3.0",
"ruff ~= 0.1.15",
"ruff ~= 0.2.1",
]
extras["docs"] = []
extras["test_prod"] = ["pytest", "pytest-xdist", "pytest-subtests", "parameterized"]
Expand Down Expand Up @@ -49,7 +49,7 @@
name="accelerate",
version="0.28.0.dev",
description="Accelerate",
long_description=open("README.md", "r", encoding="utf-8").read(),
long_description=open("README.md", encoding="utf-8").read(),
long_description_content_type="text/markdown",
keywords="deep learning",
license="Apache",
Expand Down
9 changes: 4 additions & 5 deletions src/accelerate/accelerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -430,15 +430,14 @@ def __init__(
# Mixed precision attributes
self.scaler = None
self.native_amp = False
err = "{mode} mixed precision requires {requirement}"
if (
self.state.mixed_precision == "fp16"
and self.device.type != "cpu"
and self.distributed_type not in (DistributedType.DEEPSPEED, DistributedType.MEGATRON_LM)
):
self.native_amp = True
if self.device.type not in ("xpu", "cuda", "mps", "npu"):
raise ValueError(err.format(mode="fp16", requirement="a GPU"))
raise ValueError(f"fp16 mixed precision requires a GPU (not {self.device.type!r}).")
kwargs = self.scaler_handler.to_kwargs() if self.scaler_handler is not None else {}
if self.distributed_type == DistributedType.FSDP:
from torch.distributed.fsdp.sharded_grad_scaler import ShardedGradScaler
Expand All @@ -458,7 +457,7 @@ def __init__(
else:
self.native_amp = is_bf16_available(True)
if mixed_precision == "bf16" and not self.native_amp and not is_tpu_available():
raise ValueError(err.format(mode="bf16", requirement="PyTorch >= 1.10 and a supported device."))
raise ValueError("bf16 mixed precision requires PyTorch >= 1.10 and a supported device.")

# Start of internal step tracking
self.step = 0
Expand Down Expand Up @@ -1245,7 +1244,7 @@ def prepare(self, *args, device_placement=None):
item in container
for container in (self._dataloaders, self._models, self._optimizers, self._schedulers)
):
setattr(item, "_is_accelerate_prepared", True)
item._is_accelerate_prepared = True

return result if len(result) > 1 else result[0]

Expand Down Expand Up @@ -2386,7 +2385,7 @@ def init_trackers(self, project_name: str, config: dict | None = None, init_kwar
self.trackers.append(tracker)
else:
tracker_init = LOGGER_TYPE_TO_CLASS[str(tracker)]
if getattr(tracker_init, "requires_logging_directory"):
if tracker_init.requires_logging_directory:
# We can skip this check since it was done in `__init__`
self.trackers.append(
tracker_init(project_name, self.logging_dir, **init_kwargs.get(str(tracker), {}))
Expand Down
6 changes: 3 additions & 3 deletions src/accelerate/commands/config/config_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def load_config_from_file(config_file):
)
else:
config_file = default_config_file
with open(config_file, "r", encoding="utf-8") as f:
with open(config_file, encoding="utf-8") as f:
if config_file.endswith(".json"):
if (
json.load(f).get("compute_environment", ComputeEnvironment.LOCAL_MACHINE)
Expand Down Expand Up @@ -94,7 +94,7 @@ def to_dict(self):
@classmethod
def from_json_file(cls, json_file=None):
json_file = default_json_config_file if json_file is None else json_file
with open(json_file, "r", encoding="utf-8") as f:
with open(json_file, encoding="utf-8") as f:
config_dict = json.load(f)
if "compute_environment" not in config_dict:
config_dict["compute_environment"] = ComputeEnvironment.LOCAL_MACHINE
Expand Down Expand Up @@ -126,7 +126,7 @@ def to_json_file(self, json_file):
@classmethod
def from_yaml_file(cls, yaml_file=None):
yaml_file = default_yaml_config_file if yaml_file is None else yaml_file
with open(yaml_file, "r", encoding="utf-8") as f:
with open(yaml_file, encoding="utf-8") as f:
config_dict = yaml.safe_load(f)
if "compute_environment" not in config_dict:
config_dict["compute_environment"] = ComputeEnvironment.LOCAL_MACHINE
Expand Down
14 changes: 6 additions & 8 deletions src/accelerate/commands/launch.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,19 +105,19 @@ def __call__(self, parser, namespace, values, option_string=None):
for i, arg in enumerate(opts):
# If the argument's container is outside of the used titles, hide it
if arg.container.title not in titles + used_titles:
setattr(opts[i], "help", argparse.SUPPRESS)
opts[i].help = argparse.SUPPRESS
# If the argument is hardware selection, but not being passed, hide it
elif arg.container.title == "Hardware Selection Arguments":
if set(arg.option_strings).isdisjoint(set(args)):
setattr(opts[i], "help", argparse.SUPPRESS)
opts[i].help = argparse.SUPPRESS
else:
setattr(opts[i], "help", arg.help + " (currently selected)")
opts[i].help = arg.help + " (currently selected)"
# If the argument is a training paradigm, but not being passed, hide it
elif arg.container.title == "Training Paradigm Arguments":
if set(arg.option_strings).isdisjoint(set(used_platforms)):
setattr(opts[i], "help", argparse.SUPPRESS)
opts[i].help = argparse.SUPPRESS
else:
setattr(opts[i], "help", arg.help + " (currently selected)")
opts[i].help = arg.help + " (currently selected)"
for i, group in enumerate(list(parser._action_groups)):
# If all arguments in the group are hidden, hide the group
if all([arg.help == argparse.SUPPRESS for arg in group._group_actions]):
Expand Down Expand Up @@ -924,14 +924,12 @@ def _validate_launch_command(args):
args.mixed_precision = defaults.mixed_precision
mp_from_config_flag = True
else:
native_amp = False
err = "{mode} mixed precision requires {requirement}"
if args.use_cpu or (args.use_xpu and torch.xpu.is_available()):
native_amp = is_torch_version(">=", "1.10")
else:
native_amp = is_bf16_available(True)
if args.mixed_precision == "bf16" and not native_amp and not (args.tpu and is_tpu_available()):
raise ValueError(err.format(mode="bf16", requirement="PyTorch >= 1.10 and a supported device."))
raise ValueError("bf16 mixed precision requires PyTorch >= 1.10 and a supported device.")

# Silently set the default here
if args.dynamo_backend is None:
Expand Down
8 changes: 4 additions & 4 deletions src/accelerate/commands/menu/input.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def mark(key: str):
def decorator(func):
handle = getattr(func, "handle_key", [])
handle += [key]
setattr(func, "handle_key", handle)
func.handle_key = handle
return func

return decorator
Expand All @@ -44,7 +44,7 @@ def mark_multiple(*keys: List[str]):
def decorator(func):
handle = getattr(func, "handle_key", [])
handle += keys
setattr(func, "handle_key", handle)
func.handle_key = handle
return func

return decorator
Expand All @@ -58,8 +58,8 @@ class KeyHandler(type):
def __new__(cls, name, bases, attrs):
new_cls = super().__new__(cls, name, bases, attrs)
if not hasattr(new_cls, "key_handler"):
setattr(new_cls, "key_handler", {})
setattr(new_cls, "handle_input", KeyHandler.handle_input)
new_cls.key_handler = {}
new_cls.handle_input = KeyHandler.handle_input

for value in attrs.values():
handled_keys = getattr(value, "handle_key", [])
Expand Down
2 changes: 1 addition & 1 deletion src/accelerate/commands/tpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def tpu_command_launcher(args):
raise ValueError("You must specify either a command file or a command to run on the pod.")

if args.command_file:
with open(args.command_file, "r") as f:
with open(args.command_file) as f:
args.command = [f.read().splitlines()]

# To turn list of lists into list of strings
Expand Down
8 changes: 4 additions & 4 deletions src/accelerate/test_utils/examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,14 @@ def compare_against_test(base_filename: str, feature_filename: str, parser_only:
functionalities off of "examples/nlp_example.py", so if `base_filename` is a script other than
`complete_nlp_example.py`, the template script should be included here. Such as `examples/cv_example.py`
"""
with open(base_filename, "r") as f:
with open(base_filename) as f:
base_file_contents = f.readlines()
with open(os.path.abspath(os.path.join("examples", "nlp_example.py")), "r") as f:
with open(os.path.abspath(os.path.join("examples", "nlp_example.py"))) as f:
full_file_contents = f.readlines()
with open(feature_filename, "r") as f:
with open(feature_filename) as f:
feature_file_contents = f.readlines()
if secondary_filename is not None:
with open(secondary_filename, "r") as f:
with open(secondary_filename) as f:
secondary_file_contents = f.readlines()

# This is our base, we remove all the code from here in our `full_filename` and `feature_filename` to find the new content
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# coding=utf-8
# Copyright 2022 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -182,7 +181,7 @@ def training_function(config, args):
accelerator.print("resumed checkpoint performance:", accuracy)
accelerator.print("resumed checkpoint's scheduler's lr:", lr_scheduler.get_lr()[0])
accelerator.print("resumed optimizers's lr:", optimizer.param_groups[0]["lr"])
with open(os.path.join(args.output_dir, f"state_{starting_epoch-1}.json"), "r") as f:
with open(os.path.join(args.output_dir, f"state_{starting_epoch-1}.json")) as f:
resumed_state = json.load(f)
assert resumed_state["accuracy"] == accuracy, "Accuracy mismatch, loading from checkpoint failed"
assert (
Expand Down
Loading

0 comments on commit 13e79cc

Please sign in to comment.