Skip to content

feat(tools): add HuggingFace config → architecture_config converter#198

Open
rishi-jat wants to merge 1 commit intomodelpack:mainfrom
rishi-jat:feat/hf-to-arch-tool
Open

feat(tools): add HuggingFace config → architecture_config converter#198
rishi-jat wants to merge 1 commit intomodelpack:mainfrom
rishi-jat:feat/hf-to-arch-tool

Conversation

@rishi-jat
Copy link

Summary

Add a small CLI tool that converts a HuggingFace config.json into the
ModelPack architecture_config shape for transformer models.

Scope

  • New tool: tools/hf_to_arch.py

    • Input: HuggingFace config.json
    • Output: architecture_config JSON
    • Strict validation on required fields and types
  • Tests: tools/hf_to_arch_test.py

    • End-to-end via subprocess
    • Covers success and failure cases

Mapping

  • num_hidden_layers → numLayers
  • hidden_size → hiddenSize
  • num_attention_heads → numAttentionHeads

Behavior

  • Fails if required fields are missing
  • Rejects non-integer and invalid values
  • Output is deterministic (sorted keys)

Limitations

  • Assumes standard HuggingFace field names
  • Does not attempt to handle model-specific variations
  • Only covers minimal transformer fields

These constraints are intentional. The goal is to establish a small, verifiable
baseline before expanding coverage.

Relation to #164

This is a first step toward automated generation of transformer specs from
existing models. Follow-ups can extend the mapping and integrate with the
schema and validation layers.

Signed-off-by: Rishi Jat <rishijat098@gmail.com>
Copilot AI review requested due to automatic review settings March 26, 2026 00:15
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a new command-line utility designed to streamline the process of adapting HuggingFace model configurations for use within the ModelPack ecosystem. By converting config.json files into a standardized architecture_config format, it lays foundational groundwork for automating the generation of transformer specifications, ensuring data integrity through robust validation, and facilitating future integration with schema and validation layers.

Highlights

  • New CLI Tool: Introduced tools/hf_to_arch.py to convert HuggingFace config.json files into the ModelPack architecture_config format for transformer models.
  • Robust Validation: Implemented strict validation for required fields, data types (ensuring integer values >= 1), and JSON parsing errors to maintain data integrity.
  • Key Mappings: Defined specific mappings for transformer parameters, including num_hidden_layers to numLayers, hidden_size to hiddenSize, and num_attention_heads to numAttentionHeads.
  • Comprehensive Testing: Added tools/hf_to_arch_test.py with end-to-end tests covering successful conversions, missing fields, invalid JSON, file not found errors, and incorrect data types.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces two new Python scripts: tools/hf_to_arch.py and tools/hf_to_arch_test.py. The hf_to_arch.py script converts HuggingFace config.json files into a simplified architecture_config format, specifically for transformer models, including robust validation for required integer fields. The hf_to_arch_test.py script provides comprehensive tests for the conversion utility, covering various valid and error-case scenarios. Feedback suggests improving the integer type check in hf_to_arch.py for clarity, refactoring its command-line argument parsing to use argparse for better maintainability, and migrating the test suite to pytest for a more standard and robust testing framework.

if hf_key not in hf_config:
raise ValueError(f"missing required field: {hf_key}")
value = hf_config[hf_key]
if not isinstance(value, int) or isinstance(value, bool):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current type check for integers is functionally correct but a bit subtle because it relies on bool being a subclass of int in Python, which can be non-obvious. Using type(value) is not int is a more explicit and clearer way to check that the value is strictly an integer and not a boolean.

Suggested change
if not isinstance(value, int) or isinstance(value, bool):
if type(value) is not int:

Comment on lines +33 to +37
if len(sys.argv) != 2:
print(f"usage: {sys.argv[0]} <config.json>", file=sys.stderr)
sys.exit(1)

config_path = sys.argv[1]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For better command-line interface design and maintainability, consider using the argparse module instead of manually parsing sys.argv. argparse provides automatic help messages, error handling for arguments, and is the standard way to create CLI tools in Python. You will also need to add import argparse at the top of the file.

Suggested change
if len(sys.argv) != 2:
print(f"usage: {sys.argv[0]} <config.json>", file=sys.stderr)
sys.exit(1)
config_path = sys.argv[1]
parser = argparse.ArgumentParser(description="Convert HuggingFace config.json to architecture_config format.")
parser.add_argument("config_path", help="Path to the HuggingFace config.json file.")
args = parser.parse_args()
config_path = args.config_path

Comment on lines +134 to +146
def main():
test_valid_config()
test_missing_field()
test_invalid_json()
test_file_not_found()
test_invalid_field_type()
test_zero_value()
test_bool_value()
print("\nAll tests passed.")


if __name__ == "__main__":
main()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This test file implements a custom test runner by calling test functions from main() and using print statements to show progress. While this works, adopting a standard test framework like pytest would offer several advantages:

  • No need for a manual runner (main function and if __name__ == '__main__' block).
  • More detailed and readable output on test failures.
  • A rich ecosystem of plugins.
  • Use of simple assert statements with no need for custom failure messages.

Migrating to pytest would involve removing the main function, the if __name__ == '__main__' block, and all print statements for test status. Tests could then be run with the pytest command. This would make the test suite more standard and easier to maintain.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a small Python CLI utility to convert a HuggingFace config.json into a minimal transformer architecture_config JSON shape, as an initial step toward automated transformer spec generation (Issue #164).

Changes:

  • Introduces tools/hf_to_arch.py CLI with required-field mapping and basic validation.
  • Adds an end-to-end subprocess-based test script tools/hf_to_arch_test.py covering success and several failure modes.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
tools/hf_to_arch.py New converter CLI that reads HF config JSON, validates required fields, and emits deterministic architecture config JSON.
tools/hf_to_arch_test.py New subprocess-driven tests for the converter’s success and error behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +15 to +22
def convert_hf_config(hf_config: dict) -> dict:
"""Convert HuggingFace config to architecture_config format."""
arch_config = {"type": "transformer"}

for arch_key, hf_key in REQUIRED_MAPPINGS.items():
if hf_key not in hf_config:
raise ValueError(f"missing required field: {hf_key}")
value = hf_config[hf_key]
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

convert_hf_config assumes hf_config is a dict-like JSON object. If the input JSON is a list/string/etc., the hf_key not in hf_config / hf_config[hf_key] access can raise a TypeError (or behave unexpectedly) and will bypass the current ValueError handling, resulting in a raw stack trace. Add an explicit top-level type check (e.g., require dict) and raise a ValueError with a clear message when the JSON root is not an object.

Copilot uses AI. Check for mistakes.
config_path = sys.argv[1]

try:
with open(config_path, "r") as f:
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

open(config_path, "r") relies on the platform default encoding, which can cause failures or mis-parsing on systems where the locale encoding isn’t UTF-8. Since HuggingFace config.json files are UTF-8 JSON, open the file with an explicit encoding="utf-8" for consistent behavior across environments.

Suggested change
with open(config_path, "r") as f:
with open(config_path, "r", encoding="utf-8") as f:

Copilot uses AI. Check for mistakes.
Comment on lines +134 to +146
def main():
test_valid_config()
test_missing_field()
test_invalid_json()
test_file_not_found()
test_invalid_field_type()
test_zero_value()
test_bool_value()
print("\nAll tests passed.")


if __name__ == "__main__":
main()
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test module is a standalone script (custom main() and print-based status) rather than a framework-discoverable test (e.g., pytest/unittest). In the current repo, CI/make test only runs go test, so these tests won’t execute automatically and may silently regress. Consider integrating a Python test runner into CI/Makefile or converting these checks into the repo’s existing Go test harness; if you intend to use pytest later, also rename to test_*.py and remove the manual main().

Suggested change
def main():
test_valid_config()
test_missing_field()
test_invalid_json()
test_file_not_found()
test_invalid_field_type()
test_zero_value()
test_bool_value()
print("\nAll tests passed.")
if __name__ == "__main__":
main()

Copilot uses AI. Check for mistakes.
@rishi-jat
Copy link
Author

/cc @aftersnow
/cc @bergwolf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants