Files
wehub-resource-sync a203934033
Lint test / lint (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:34:58 +08:00

133 lines
6.3 KiB
Python

# Copyright (c) ModelScope Contributors. All rights reserved.
import os
import shutil
import torch.distributed as dist
from transformers.utils import strtobool
from typing import List, Optional, Union
from swift.megatron.arguments import MegatronExportArguments
from swift.megatron.convert import test_convert_precision
from swift.megatron.model import get_mcore_model
from swift.megatron.utils import load_mcore_checkpoint, prepare_mcore_model, save_mcore_checkpoint
from swift.pipelines import SwiftPipeline, prepare_model_template
from swift.utils import disable_safe_ddp_context_use_barrier, get_logger, is_master
logger = get_logger()
class MegatronExport(SwiftPipeline):
args_class = MegatronExportArguments
args: args_class
def run(self):
os.environ['DISABLE_MP_DDP'] = 'true'
args = self.args
if args.to_hf:
self.convert_mcore2hf()
elif args.to_mcore:
self.convert_hf2mcore()
def convert_mcore2hf(self) -> None:
args = self.args
args.experts_impl = 'eager'
download_model = args.model is not None
_, template = prepare_model_template(args, load_model=False, download_model=download_model)
self.processor = template.processor
hf_config = self.processor.model_info.config
mg_model = get_mcore_model(args, hf_config)[0]
logger.info('Megatron model created successfully.')
bridge = mg_model.config.bridge
if args.mcore_model is not None:
load_mcore_checkpoint(args, [mg_model], load_arg='mcore_model')
elif args.model is not None:
bridge.load_weights([mg_model], args.model_info.model_dir)
else:
raise ValueError('Please specify `--mcore_model` or `--model`.')
if args.adapters or args.mcore_adapter is not None:
peft_model = prepare_mcore_model(args, mg_model)
if args.mcore_adapter is not None:
load_mcore_checkpoint(args, [mg_model], load_arg='mcore_adapter')
elif args.adapters:
assert len(args.adapters) == 1, 'Currently only support one adapter'
bridge.load_weights([mg_model], args.adapters[0], peft_format=True)
if args.merge_lora:
logger.info('Merge LoRA...')
mg_model = peft_model.merge_and_unload()
logger.info('Converting weights and saving the model...')
save_peft_format = args.tuner_type == 'lora' and not args.merge_lora
bridge.save_weights(
[mg_model],
args.output_dir,
peft_format=save_peft_format,
args=args,
processor=self.processor,
)
if is_master():
if args.ckpt_dir:
args_path = os.path.join(args.ckpt_dir, 'args.json')
shutil.copy(args_path, os.path.join(args.output_dir, 'args.json'))
else:
args.save_args(args.output_dir)
if args.test_convert_precision:
with disable_safe_ddp_context_use_barrier():
if save_peft_format:
kwargs = {'adapters': [args.output_dir]}
else:
kwargs = {'model': args.output_dir, 'torch_dtype': None, 'adapters': []}
device_map = args.device_map or 'auto'
hf_model, template = prepare_model_template(
args, device_map=device_map, **kwargs) if is_master() else (None, template)
test_convert_precision(args, hf_model, mg_model, template, test_convert_dtype=args.test_convert_dtype)
dist.barrier()
def convert_hf2mcore(self) -> None:
args = self.args
args.experts_impl = 'eager'
download_model = args.model is not None
_, template = prepare_model_template(args, load_model=False, download_model=download_model)
self.processor = template.processor
hf_config = self.processor.model_info.config
mg_model = get_mcore_model(args, hf_config)[0]
logger.info('Megatron model created successfully.')
bridge = mg_model.config.bridge
if args.model is not None:
bridge.load_weights([mg_model], args.model_info.model_dir)
elif args.mcore_model is not None:
load_mcore_checkpoint(args, [mg_model], load_arg='mcore_model')
else:
raise ValueError('Please specify `--mcore_model` or `--model`.')
dist.barrier()
if args.adapters or args.mcore_adapter is not None:
peft_model = prepare_mcore_model(args, mg_model)
if args.adapters:
assert len(args.adapters) == 1, 'Currently only support one adapter'
bridge.load_weights([mg_model], args.adapters[0], peft_format=True)
elif args.mcore_adapter is not None:
load_mcore_checkpoint(args, [mg_model], load_arg='mcore_adapter')
if args.merge_lora:
logger.info('Merge LoRA...')
mg_model = peft_model.merge_and_unload()
logger.info('Successfully transferred HF model weights to MG model.')
_test_convert_precision = strtobool(os.getenv('SWIFT_TEST_CONVERT_PRECISION', '0'))
if not _test_convert_precision:
args.save_args(args.output_dir)
logger.info('Saving the model...')
save_peft_format = args.tuner_type == 'lora' and not args.merge_lora
save_mcore_checkpoint(args, [mg_model], peft_format=save_peft_format)
# hf_model does not support loading args.mcore_adapter, so test_convert_precision cannot be performed
support_convert_precision = args.mcore_adapter is None
if args.test_convert_precision:
if support_convert_precision:
with disable_safe_ddp_context_use_barrier():
device_map = args.device_map or 'auto'
hf_model, template = prepare_model_template(
args, device_map=device_map) if is_master() else (None, template)
test_convert_precision(args, hf_model, mg_model, template, test_convert_dtype=args.test_convert_dtype)
dist.barrier()
else:
logger.warning('Skip test_convert_precision because `--mcore_adapter` is specified.')
def megatron_export_main(args: Optional[Union[List[str], MegatronExportArguments]] = None):
return MegatronExport(args).main()