Skip to content

Commit 4123b62

Browse files
committed
format
1 parent 2453eac commit 4123b62

3 files changed

Lines changed: 80 additions & 56 deletions

File tree

flagscale/train/peft/lora.py

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
1-
import torch
2-
import torch.nn as nn
3-
from typing import Any, Callable, List, Optional, Tuple, Type, Dict
4-
from dataclasses import dataclass, field
1+
import logging
2+
53
from collections import namedtuple
4+
from dataclasses import dataclass, field
65
from functools import partial
7-
import logging
6+
from typing import Any, Callable, Dict, List, Optional, Tuple, Type
7+
8+
import torch
9+
import torch.nn as nn
10+
11+
from megatron.training.utils import unwrap_model
812

913
from flagscale.train.peft.peft import PEFT, AdapterWrapper
1014
from flagscale.train.peft.utils import (
15+
ParallelLinearAdapter,
1116
get_adapter_attributes_from_linear,
1217
is_expert_linear,
13-
ParallelLinearAdapter,
1418
match_module,
1519
)
16-
from megatron.training.utils import unwrap_model
1720

1821

1922
class LoRALinear(AdapterWrapper):
@@ -25,10 +28,7 @@ class to provide a specific implementation of the forward method.
2528
"""
2629

2730
def forward(
28-
self,
29-
x: torch.Tensor,
30-
*args,
31-
**kwargs,
31+
self, x: torch.Tensor, *args, **kwargs
3232
) -> tuple[torch.Tensor, Optional[torch.Tensor]]:
3333
# pylint: disable=C0115,C0116
3434
linear_output, bias, layernorm_output = self.base_linear_forward(x, *args, **kwargs)
@@ -44,10 +44,8 @@ class LoRA(PEFT, peft_type='lora'):
4444
LoRA uses a low-rank projection to adapt the weights of a pre-trained model to a new downstream task.
4545
This class facilitates the application of LoRA to specific modules within the model architecture.
4646
"""
47-
def __init__(
48-
self,
49-
config,
50-
):
47+
48+
def __init__(self, config):
5149
super().__init__()
5250
self.config = config
5351
self.target_modules = config.lora_target_modules
@@ -72,9 +70,13 @@ def transform(self, m: nn.Module, name=None, prefix=None):
7270
if (ans := match_module(m, name, prefix, self.target_modules)) is not None:
7371
(match, full_name) = ans
7472

75-
input_is_parallel, in_features, out_features, disable_sp_comm, base_linear_is_parallel = (
76-
get_adapter_attributes_from_linear(m)
77-
)
73+
(
74+
input_is_parallel,
75+
in_features,
76+
out_features,
77+
disable_sp_comm,
78+
base_linear_is_parallel,
79+
) = get_adapter_attributes_from_linear(m)
7880

7981
adapter = ParallelLinearAdapter(
8082
in_features=in_features,
@@ -94,12 +96,11 @@ def transform(self, m: nn.Module, name=None, prefix=None):
9496

9597
lora_linear = LoRALinear(m, adapter)
9698
return lora_linear
97-
99+
98100
return m
99-
101+
100102
def freeze_model(self, model: nn.Module):
101-
"""Freeze main model for lora
102-
"""
103+
"""Freeze main model for lora"""
103104
for name, param in model.named_parameters():
104105
param.requires_grad = False
105106
for name, param in model.named_parameters():
@@ -115,7 +116,7 @@ def load_state_dict_hook_remap_main_model_params(
115116
strict: bool,
116117
missing_keys: List[str],
117118
unexpected_keys: List[str],
118-
errors: List[Any]
119+
errors: List[Any],
119120
):
120121
old_keys = [prefix + "weight", prefix + "bias"]
121122
new_keys = [prefix + "to_wrap.weight", prefix + "to_wrap.bias"]
@@ -125,7 +126,7 @@ def load_state_dict_hook_remap_main_model_params(
125126
state_dict[new_key] = state_dict.pop(old_key)
126127
else:
127128
state_dict.pop(old_key)
128-
129+
129130
for name, module in model.named_modules():
130131
if isinstance(module, LoRALinear):
131132
module.register_load_state_dict_pre_hook(
@@ -142,13 +143,11 @@ def load_state_dict_hook_ignore_param_names(
142143
f"{param_name} being removed from incompatible_keys.missing_keys in this model"
143144
)
144145
incompatible_keys.missing_keys.remove(param_name)
146+
145147
lora_param_names = []
146148
for name in model.state_dict().keys():
147149
if "adapter" in name:
148150
lora_param_names.append(name)
149151
model.register_load_state_dict_post_hook(
150-
partial(
151-
load_state_dict_hook_ignore_param_names,
152-
lora_param_names,
153-
)
152+
partial(load_state_dict_hook_ignore_param_names, lora_param_names)
154153
)

flagscale/train/peft/peft.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
from abc import ABC, abstractmethod
2+
from typing import Any, Callable, Dict, List, Optional, Tuple, Type
3+
14
import torch
25
import torch.nn as nn
3-
from typing import Any, Callable, List, Optional, Tuple, Type, Dict
4-
from abc import ABC, abstractmethod
56

67

78
class PEFT(ABC):
@@ -11,6 +12,7 @@ class PEFT(ABC):
1112
large language models efficiently by modifying only a small subset of the model's
1213
parameters.
1314
"""
15+
1416
_REGISTRY: Dict[str, Type["PEFT"]] = {}
1517

1618
def __init_subclass__(cls, *, peft_type: str, **kwargs):
@@ -19,14 +21,14 @@ def __init_subclass__(cls, *, peft_type: str, **kwargs):
1921
raise ValueError(f"peft_type={peft_type} registered already!")
2022
cls._REGISTRY[peft_type] = cls
2123
cls._peft_type = peft_type
22-
24+
2325
@classmethod
2426
def from_config(cls, config) -> "PEFT":
2527
peft_type = config.peft_type
2628
if peft_type not in cls._REGISTRY:
2729
raise KeyError(f"Unsupported peft_type: {peft_type}, registered: {list(cls._REGISTRY)}")
2830
sub_cls = cls._REGISTRY[peft_type]
29-
return sub_cls(config)
31+
return sub_cls(config)
3032

3133
@abstractmethod
3234
def transform(self, module, name=None, prefix=None):
@@ -60,10 +62,9 @@ def apply_transform(self, model: nn.Module):
6062
if replaced_module == module:
6163
continue
6264
model.set_submodule(full_name, replaced_module)
63-
65+
6466
def freeze_model(self, model: nn.Module):
65-
"""Apply a default freeze method to the model.
66-
"""
67+
"""Apply a default freeze method to the model."""
6768
pass
6869

6970
def load_state_dict_pre_hooks(self, model: nn.Module):
@@ -144,5 +145,7 @@ def state_dict(self, destination=None, prefix='', keep_vars=False):
144145
# Get state dict of the main module
145146
self.to_wrap.state_dict(destination=destination, prefix=prefix, keep_vars=keep_vars)
146147
# Store adapter state dict under the "adapter" prefix in the destination dict
147-
self.adapter.state_dict(destination=destination, prefix=f'{prefix}adapter.', keep_vars=keep_vars)
148+
self.adapter.state_dict(
149+
destination=destination, prefix=f'{prefix}adapter.', keep_vars=keep_vars
150+
)
148151
return destination

flagscale/train/peft/utils.py

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import math
22
import re
3+
34
from importlib.metadata import version
45
from typing import Any, Callable, List, Optional, Tuple, Type
56

67
import packaging
78
import torch
9+
810
from torch import nn
911

1012
from megatron.core import ModelParallelConfig, parallel_state
@@ -18,13 +20,14 @@
1820

1921
try:
2022
from megatron.core.extensions.transformer_engine import (
23+
TEColumnParallelGroupedLinear,
2124
TEColumnParallelLinear,
2225
TELayerNormColumnParallelLinear,
23-
TEColumnParallelGroupedLinear,
24-
TERowParallelLinear,
25-
TERowParallelGroupedLinear,
2626
TELinear,
27+
TERowParallelGroupedLinear,
28+
TERowParallelLinear,
2729
)
30+
2831
HAVE_TE = True
2932
except ImportError:
3033
HAVE_TE = False
@@ -34,8 +37,7 @@
3437

3538

3639
def match_module(m, name, prefix, target_modules):
37-
"""
38-
"""
40+
""" """
3941
full_name = f"{prefix}.{name}" if prefix else name
4042
for pattern in target_modules:
4143
if name == pattern or wildcard_match(pattern, full_name):
@@ -117,7 +119,13 @@ def get_adapter_attributes_from_linear(m: nn.Module):
117119
else:
118120
raise NotImplementedError(f"Layer type is unrecognized for LoRA: {type(m)}")
119121

120-
return input_is_parallel, in_features, out_features, disable_sequence_parallel_comm, base_linear_is_parallel
122+
return (
123+
input_is_parallel,
124+
in_features,
125+
out_features,
126+
disable_sequence_parallel_comm,
127+
base_linear_is_parallel,
128+
)
121129

122130

123131
def is_expert_linear(fqn):
@@ -188,7 +196,9 @@ def __init__(
188196
if model_parallel_config is None:
189197
model_parallel_config = ModelParallelConfig()
190198
_sequence_parallel = model_parallel_config.sequence_parallel
191-
model_parallel_config.sequence_parallel = False # SP is irrelevant for the lora linear layer
199+
model_parallel_config.sequence_parallel = (
200+
False # SP is irrelevant for the lora linear layer
201+
)
192202
self.config = model_parallel_config
193203

194204
if input_is_parallel:
@@ -215,7 +225,7 @@ def __init__(
215225
symmetric_ar_type=model_parallel_config.symmetric_ar_type,
216226
skip_weight_param_allocation=False,
217227
)
218-
228+
219229
if input_is_parallel:
220230
self.linear_out = TELinear(
221231
input_size=dim,
@@ -246,7 +256,7 @@ def __init__(
246256
self.dropout = torch.nn.Dropout(p=dropout)
247257
else:
248258
self.dropout = None
249-
259+
250260
# revert config change in case it is read elsewhere
251261
model_parallel_config.sequence_parallel = _sequence_parallel
252262
self.disable_sequence_parallel_comm = disable_sequence_parallel_comm
@@ -271,26 +281,34 @@ def forward(self, x):
271281
if self.dropout is not None and self.dropout_position == 'pre':
272282
x = self.dropout(x)
273283

274-
if not self.disable_sequence_parallel_comm and not self.input_is_parallel and not self.is_expert:
284+
if (
285+
not self.disable_sequence_parallel_comm
286+
and not self.input_is_parallel
287+
and not self.is_expert
288+
):
275289
# for attention_qkv and linear_fc1
276290
# layernorm before lora is impacted by sequence parallel,
277291
# hence seq dim need to be gathered right before lora linear layers
278292
# this function also handles the backward pass correctly
279293
x = gather_from_sequence_parallel_region(x)
280-
281-
x, _= self.linear_in(x)
282-
x, _= self.linear_out(x)
283294

284-
if not self.disable_sequence_parallel_comm and self.input_is_parallel and not self.is_expert:
295+
x, _ = self.linear_in(x)
296+
x, _ = self.linear_out(x)
297+
298+
if (
299+
not self.disable_sequence_parallel_comm
300+
and self.input_is_parallel
301+
and not self.is_expert
302+
):
285303
# for attention_dense and linear_fc2
286304
# layernorm after lora is impacted by sequence parallel,
287305
# hence seq dim need to be scattered right after lora linear layers
288306
# this function also handles the backward pass correctly
289307
x = scatter_to_sequence_parallel_region(x)
290-
308+
291309
if self.dropout is not None and self.dropout_position == 'post':
292310
x = self.dropout(x)
293-
311+
294312
x = x * (self.alpha / self.dim)
295313

296314
return x
@@ -303,17 +321,21 @@ def sharded_state_dict(
303321
since TP is sharded separately for the two logical matrices (gate and up)
304322
"""
305323
sharded_state_dict = {}
306-
linear_in_sd = self.linear_in.sharded_state_dict(f"{prefix}linear_in.", sharded_offsets, metadata)
307-
linear_out_sd = self.linear_out.sharded_state_dict(f"{prefix}linear_out.", sharded_offsets, metadata)
324+
linear_in_sd = self.linear_in.sharded_state_dict(
325+
f"{prefix}linear_in.", sharded_offsets, metadata
326+
)
327+
linear_out_sd = self.linear_out.sharded_state_dict(
328+
f"{prefix}linear_out.", sharded_offsets, metadata
329+
)
308330

309331
sharded_state_dict.update(linear_in_sd)
310332
sharded_state_dict.update(linear_out_sd)
311333
return sharded_state_dict
312-
334+
313335
def __repr__(self):
314336
return (
315337
f"{type(self).__name__}(linear_in: in_features={self.linear_in.in_features}, "
316338
f"out_features={self.linear_in.out_features}, bias={self.linear_in.use_bias}, TP={self.linear_in.tp_size}), "
317339
f"(linear_out: in_features={self.linear_out.in_features}, "
318340
f"out_features={self.linear_out.out_features}, bias={self.linear_out.use_bias}, TP={self.linear_out.tp_size})"
319-
)
341+
)

0 commit comments

Comments
 (0)