linting-and-formatting

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Linting and Formatting

代码检查与格式化

Single source of truth for code style in Megatron Bridge. Read this before writing new code or reviewing PRs.
Megatron Bridge代码风格的唯一权威参考。编写新代码或审查PR前请阅读本文。

Style Guides

风格指南

Target Python 3.10+.
目标Python版本为3.10+。

Formatting and Linting

格式化与代码检查

Run before every commit:
bash
uv run ruff check --fix .
uv run ruff format .
Pre-commit hooks run these automatically. If hooks auto-fix files, re-stage and re-run until clean:
bash
git add -u
pre-commit run
每次提交前请运行以下命令:
bash
uv run ruff check --fix .
uv run ruff format .
预提交钩子会自动执行这些操作。如果钩子自动修复了文件,请重新暂存并再次运行直到无问题:
bash
git add -u
pre-commit run

if it auto-fixed files:

如果自动修复了文件:

git add -u pre-commit run
undefined
git add -u pre-commit run
undefined

Ruff Rules (from
ruff.toml
)

Ruff规则(来自
ruff.toml

RuleIDDescription
Line length119 characters (formatter)
Quote styleDouble quotes
f-string without placeholdersF541Error
Unused local variableF841Auto-removed by
--fix
Unused importF401Auto-removed by
--fix
(ignored in
__init__.py
)
Ambiguous variable nameE741Error (e.g.,
l
,
O
,
I
)
Undefined nameF821Error
Block comment formatE266Error (too many
#
)
Import sortingIisort-compatible, auto-fixed
Public class docstringD101Warning (ignored in test files)
Public function docstringD103Warning (ignored in test files)
Per-file overrides:
  • __init__.py
    : F401 and F403 ignored (re-exports expected).
  • test_*.py
    ,
    *_test.py
    ,
    tests/*.py
    : D101 and D103 ignored.
规则ID描述
行长度119个字符(格式化工具)
引号风格双引号
无占位符的f-stringF541错误
未使用的局部变量F841
--fix
自动移除
未使用的导入F401
--fix
自动移除(
__init__.py
中忽略)
模糊变量名E741错误(例如
l
O
I
未定义名称F821错误
块注释格式E266错误(过多
#
导入排序I与isort兼容,自动修复
公共类文档字符串D101警告(测试文件中忽略)
公共函数文档字符串D103警告(测试文件中忽略)
按文件覆盖规则:
  • __init__.py
    :忽略F401和F403(允许重新导出)。
  • test_*.py
    *_test.py
    tests/*.py
    :忽略D101和D103。

Naming Conventions

命名约定

KindConventionExample
Filessnake_case
model_bridge.py
ClassesPascalCase
MegatronModelBridge
Functions/methodssnake_case
load_weights_hf_to_megatron
Local variablessnake_case
megatron_weights
Variables starting with digitprefix
k
k_99th_percentile
Global variablesUPPER_SNAKE + prefix
G
G_LOGGER
ConstantsUPPER_SNAKE
DEFAULT_HIDDEN_SIZE
  • Avoid shadowing variables from an outer scope.
  • Initialize all externally visible class members in the constructor.
类型约定示例
文件snake_case
model_bridge.py
PascalCase
MegatronModelBridge
函数/方法snake_case
load_weights_hf_to_megatron
局部变量snake_case
megatron_weights
以数字开头的变量前缀
k
k_99th_percentile
全局变量UPPER_SNAKE + 前缀
G
G_LOGGER
常量UPPER_SNAKE
DEFAULT_HIDDEN_SIZE
  • 避免遮蔽外部作用域的变量。
  • 所有对外可见的类成员需在构造函数中初始化。

Import Order

导入顺序

  1. __future__
    imports
  2. Standard library
  3. Third-party (
    megatron.core
    ,
    torch
    ,
    transformers
    , etc.)
  4. First-party (
    megatron.bridge.*
    )
  5. Local folder imports
Separate groups with blank lines. ruff auto-fixes via the
I
rule.
  1. __future__
    导入
  2. 标准库
  3. 第三方库(
    megatron.core
    torch
    transformers
    等)
  4. 第一方库(
    megatron.bridge.*
  5. 本地文件夹导入
不同组之间用空行分隔。ruff会通过
I
规则自动修复导入顺序。

Type Hints

类型提示

Required on all public API functions and methods.
  • Use
    T | None
    instead of
    Optional[T]
  • Use
    X | Y
    instead of
    Union[X, Y]
  • Use built-in generics (
    list
    ,
    dict
    ,
    tuple
    ) instead of
    typing
    equivalents
python
def get_module_by_name(
    model: torch.nn.Module,
    name: str,
    default: torch.nn.Module | None = None,
) -> torch.nn.Module | None:
    ...
所有公共API函数和方法都必须添加类型提示。
  • 使用
    T | None
    替代
    Optional[T]
  • 使用
    X | Y
    替代
    Union[X, Y]
  • 使用内置泛型(
    list
    dict
    tuple
    )替代
    typing
    模块中的等效类型
python
def get_module_by_name(
    model: torch.nn.Module,
    name: str,
    default: torch.nn.Module | None = None,
) -> torch.nn.Module | None:
    ...

Mypy

Mypy

Run on changed files before submitting:
bash
uv run mypy --strict path/to/file.py
Key rules:
  • No
    Any
    leaks
    — use
    object
    for unknown types or a
    TypeVar
    for generics.
  • No untyped defs — every function must have parameter and return annotations.
  • No implicit
    Optional
    — write
    x: int | None = None
    , never
    x: int = None
    .
  • Explicit casts — use
    typing.cast()
    only when inference fails; add a comment.
  • Typed dictionaries — prefer
    TypedDict
    over
    dict[str, Any]
    for structured dicts.
  • Callable signatures — use
    Callable[[ArgType], ReturnType]
    or
    Protocol
    .
  • Ignore sparingly
    # type: ignore[code]
    must include the error code and justification.
提交前请对修改的文件运行:
bash
uv run mypy --strict path/to/file.py
核心规则:
  • 禁止
    Any
    类型泄漏
    —— 未知类型使用
    object
    ,泛型使用
    TypeVar
  • 禁止无类型定义 —— 每个函数必须有参数和返回值注解。
  • 禁止隐式
    Optional
    —— 需写成
    x: int | None = None
    ,绝不能写成
    x: int = None
  • 显式类型转换 —— 仅当类型推断失败时使用
    typing.cast()
    ,并添加注释说明。
  • 类型化字典 —— 结构化字典优先使用
    TypedDict
    而非
    dict[str, Any]
  • 可调用签名 —— 使用
    Callable[[ArgType], ReturnType]
    Protocol
  • 谨慎忽略类型错误 ——
    # type: ignore[code]
    必须包含错误代码和理由。

Keyword-Only Arguments for Ambiguous Parameters

模糊参数使用仅关键字参数

When a function has multiple parameters of the same type that could be swapped by mistake, use
*
to force keyword-only arguments.
python
undefined
当函数存在多个同类型参数,容易被误交换时,使用
*
强制使用仅关键字参数。
python
undefined

Don't

不推荐

def scatter_weights(tensor: Tensor, tp_group: ProcessGroup, ep_group: ProcessGroup): ...
def scatter_weights(tensor: Tensor, tp_group: ProcessGroup, ep_group: ProcessGroup): ...

Do

推荐

def scatter_weights(tensor: Tensor, *, tp_group: ProcessGroup, ep_group: ProcessGroup): ...
undefined
def scatter_weights(tensor: Tensor, *, tp_group: ProcessGroup, ep_group: ProcessGroup): ...
undefined

Docstrings

文档字符串

Google-style for public classes and functions:
python
def convert_weights(
    source_model: torch.nn.Module,
    target_model: torch.nn.Module,
    mapping: MegatronParamMapping,
) -> dict[str, torch.Tensor]:
    """Convert weights from source to target model format.

    Args:
        source_model: The source model containing weights to convert.
        target_model: The target model that will receive converted weights.
        mapping: Parameter mapping defining the conversion rules.

    Returns:
        Dictionary mapping parameter names to converted weight tensors.

    Raises:
        ValueError: If source and target models have incompatible shapes.
    """
公共类和函数使用Google风格:
python
def convert_weights(
    source_model: torch.nn.Module,
    target_model: torch.nn.Module,
    mapping: MegatronParamMapping,
) -> dict[str, torch.Tensor]:
    """将权重从源模型格式转换为目标模型格式。

    参数:
        source_model: 包含待转换权重的源模型。
        target_model: 将接收转换后权重的目标模型。
        mapping: 定义转换规则的参数映射。

    返回:
        参数字典,键为参数名称,值为转换后的权重张量。

    异常:
        ValueError: 如果源模型和目标模型的形状不兼容。
    """

Comments

注释

  • Commented-out code must have a comment explaining why. Otherwise remove it.
  • Comments explain non-obvious intent, trade-offs, or constraints — not what the code does.
  • 被注释掉的代码必须附带说明原因的注释,否则请删除。
  • 注释用于解释非显而易见的意图、权衡或约束,而非代码的功能。

Logging

日志

Use
logging.getLogger(__name__)
for module-level loggers. Use
print_rank_0
/
warn_rank_0
for user-facing messages in distributed contexts.
python
undefined
模块级日志使用
logging.getLogger(__name__)
。在分布式环境中,面向用户的消息使用
print_rank_0
/
warn_rank_0
python
undefined

Don't

不推荐

print(f"Loading weights for {model_name}")
print(f"Loading weights for {model_name}")

Do

推荐

logger = logging.getLogger(name) logger.info("Loading weights for %s", model_name)
undefined
logger = logging.getLogger(name) logger.info("Loading weights for %s", model_name)
undefined

Error Handling

错误处理

Use specific exceptions. Keep try bodies minimal.
python
try:
    state_dict = torch.load(path)
except FileNotFoundError:
    raise ValueError(f"Checkpoint not found at {path}") from None
else:
    result = convert(state_dict)
使用具体的异常类型。try代码块应尽可能精简。
python
try:
    state_dict = torch.load(path)
except FileNotFoundError:
    raise ValueError(f"Checkpoint not found at {path}") from None
else:
    result = convert(state_dict)

Avoid Reflection

避免反射

python
undefined
python
undefined

Don't

不推荐

def make_config(*args): x, y = args return dict(**locals())
def make_config(*args): x, y = args return dict(**locals())

Do

推荐

def make_config(x, y): return {"x": x, "y": y}
undefined
def make_config(x, y): return {"x": x, "y": y}
undefined

Configuration and Dataclasses

配置与数据类

  • Use
    dataclasses
    or
    NamedTuple
    for configuration objects.
  • Do not add arbitrary defaults — be explicit about required vs optional fields.
  • 使用
    dataclasses
    NamedTuple
    作为配置对象。
  • 不要添加任意默认值——明确区分必填字段和可选字段。

NVIDIA Copyright Header

NVIDIA版权头

Add to all new Python files and shell scripts (not test files). Use the current year.
python
undefined
所有新的Python文件和Shell脚本(测试文件除外)都需添加。使用当前年份。
python
undefined

Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved.

Copyright (c) 2026, NVIDIA CORPORATION. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");

Licensed under the Apache License, Version 2.0 (the "License");

you may not use this file except in compliance with the License.

you may not use this file except in compliance with the License.

You may obtain a copy of the License at

You may obtain a copy of the License at

Unless required by applicable law or agreed to in writing, software

Unless required by applicable law or agreed to in writing, software

distributed under the License is distributed on an "AS IS" BASIS,

distributed under the License is distributed on an "AS IS" BASIS,

WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

See the License for the specific language governing permissions and

See the License for the specific language governing permissions and

limitations under the License.

limitations under the License.

undefined
undefined

Code Review Checklist

代码审查检查清单

  1. Copyright header present on new Python files (not test files)
  2. Type hints on public functions and methods
  3. Docstrings on public classes and functions (Google style)
  4. Specific exceptions in try-except blocks
  5. No bare
    print()
    — use
    logger
    or
    print_rank_0
  6. No hidden defaults in config function parameters
  7. Keyword-only args for ambiguous same-type parameters
  8. Double quotes for strings
  9. Import order follows the 5-group convention
  10. No commented-out code without explanation
  11. Mypy clean — no untyped defs, no
    Any
    in public APIs, no bare
    # type: ignore
  1. 版权头:新Python文件(测试文件除外)需包含版权头
  2. 类型提示:公共函数和方法需添加类型提示
  3. 文档字符串:公共类和函数需添加Google风格的文档字符串
  4. 具体异常:try-except块中使用具体异常类型
  5. 禁止裸
    print()
    :使用
    logger
    print_rank_0
  6. 无隐藏默认值:配置函数参数中无隐藏默认值
  7. 仅关键字参数:模糊的同类型参数使用仅关键字参数
  8. 双引号:字符串使用双引号
  9. 导入顺序:遵循5组约定
  10. 无无注释的注释代码:无注释说明的注释代码需删除
  11. Mypy检查通过:无未类型化定义、公共API中无
    Any
    类型、无裸
    # type: ignore