mirror of
https://github.com/volcengine/verl.git
synced 2025-10-21 06:10:30 +08:00
### What does this PR do? This PR safely bumps python version to 3.10 for two reasons: 1. [`removeprefix`](https://docs.python.org/3.9/whatsnew/3.9.html#new-string-methods-to-remove-prefixes-and-suffixes) was introduced in python 3.9588f9728f3/verl/single_controller/ray/base.py (L498-L505)
2. [`match`](https://docs.python.org/3.10/whatsnew/3.10.html#simple-pattern-match-to-a-literal) was introduced in python 3.10588f9728f3/verl/tools/utils/tool_registry.py (L81-L92)
### Checklist Before Starting - [x] Search for similar PRs. Paste at least one query link here: ... - [x] Format the PR title as `[{modules}] {type}: {description}` (This will be checked by the CI) - `{modules}` include `fsdp`, `megatron`, `sglang`, `vllm`, `rollout`, `trainer`, `ci`, `training_utils`, `recipe`, `hardware`, `deployment`, `ray`, `worker`, `single_controller`, `misc`, `perf`, `model`, `algo`, `env`, `tool`, `ckpt`, `doc`, `data` - If this PR involves multiple modules, separate them with `,` like `[megatron, fsdp, doc]` - `{type}` is in `feat`, `fix`, `refactor`, `chore`, `test` - If this PR breaks any API (CLI arguments, config, function signature, etc.), add `[BREAKING]` to the beginning of the title. - Example: `[BREAKING][fsdp, megatron] feat: dynamic batching` ### Checklist Before Submitting > [!IMPORTANT] > Please check all the following items before requesting a review, otherwise the reviewer might deprioritize this PR for review. - [x] Read the [Contribute Guide](https://github.com/volcengine/verl/blob/main/CONTRIBUTING.md). - [x] Apply [pre-commit checks](https://github.com/volcengine/verl/blob/main/CONTRIBUTING.md#code-linting-and-formatting): `pre-commit install && pre-commit run --all-files --show-diff-on-failure --color=always` - [x] Add / Update [the documentation](https://github.com/volcengine/verl/tree/main/docs). - [ ] Add unit or end-to-end test(s) to [the CI workflow](https://github.com/volcengine/verl/tree/main/.github/workflows) to cover all the code. If not feasible, explain why: ... - [ ] Once your PR is ready for CI, send a message in [the `ci-request` channel](https://verl-project.slack.com/archives/C091TCESWB1) in [the `verl` Slack workspace](https://join.slack.com/t/verl-project/shared_invite/zt-3855yhg8g-CTkqXu~hKojPCmo7k_yXTQ).
96 lines
3.6 KiB
Python
96 lines
3.6 KiB
Python
# Copyright 2025 Bytedance Ltd. and/or its affiliates
|
|
# Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
"""
|
|
This script override a model with custom config and random weights, mainly for create small models for
|
|
debugging purposes.
|
|
|
|
Usage:
|
|
python scripts/init_random_model.py \
|
|
--hf_model_path <path_to_hf_model> \
|
|
--new_config_path <path_to_new_config.json> \
|
|
--output_path <path_to_output_model>
|
|
|
|
"""
|
|
|
|
import argparse
|
|
import json
|
|
import os
|
|
import warnings
|
|
from typing import Any
|
|
|
|
from transformers import AutoConfig, AutoModelForCausalLM, AutoTokenizer, PretrainedConfig
|
|
|
|
|
|
def _init_args():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument("--hf_model_path", type=str, required=True, help="The path for the huggingface model")
|
|
parser.add_argument("--new_config_path", type=str, required=True, help="The path for the new config file")
|
|
parser.add_argument("--output_path", type=str, required=True, help="The path for the output random model")
|
|
args = parser.parse_args()
|
|
return args
|
|
|
|
|
|
def check_output_path(output_path: str):
|
|
if os.path.exists(output_path):
|
|
warnings.warn(f"Output path '{output_path}' already exists. Will do nothing.", stacklevel=2)
|
|
exit()
|
|
else:
|
|
os.makedirs(output_path, exist_ok=True)
|
|
print(f"Output path '{output_path}' created.")
|
|
|
|
|
|
def check_configs(original_config: dict[str, Any], new_config: dict[str, Any]) -> bool:
|
|
"""
|
|
Check if the original config and new config are compatible.
|
|
This is a placeholder function; actual implementation may vary based on requirements.
|
|
"""
|
|
# Example check: ensure 'model_type' is the same
|
|
if new_config.get("model_type", None) is not None and original_config.get("model_type") != new_config.get(
|
|
"model_type"
|
|
):
|
|
raise RuntimeError("Model types do not match.")
|
|
for key in new_config:
|
|
if key not in original_config:
|
|
warnings.warn(
|
|
f"Key '{key}' in new config does not exist in original config, may not take effect.", stacklevel=2
|
|
)
|
|
|
|
|
|
def init_random_model(hf_model_path, new_config_path, output_path):
|
|
config = AutoConfig.from_pretrained(hf_model_path)
|
|
tokenizer = AutoTokenizer.from_pretrained(hf_model_path)
|
|
config_dict = PretrainedConfig.get_config_dict(hf_model_path)[0]
|
|
print(config_dict)
|
|
with open(new_config_path) as f:
|
|
new_config_dict = json.load(f)
|
|
check_configs(config_dict, new_config_dict)
|
|
config_dict.update(new_config_dict)
|
|
new_confg = config.from_dict(config_dict)
|
|
print(f"new_config: {new_confg}")
|
|
model = AutoModelForCausalLM.from_config(new_confg)
|
|
model.save_pretrained(output_path)
|
|
tokenizer.save_pretrained(output_path)
|
|
new_confg.save_pretrained(output_path)
|
|
print(f"Random model initialized and saved to {output_path}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
args = _init_args()
|
|
check_output_path(args.output_path)
|
|
init_random_model(
|
|
hf_model_path=args.hf_model_path, new_config_path=args.new_config_path, output_path=args.output_path
|
|
)
|