{
"$type": "site.standard.document",
"bskyPostRef": {
"cid": "bafyreigvzp2h53wc7n75vpbeh3btf55j3tn7t7e4tisnwo6ru2gcqqm36e",
"uri": "at://did:plc:pgryn3ephfd2xgft23qokfzt/app.bsky.feed.post/3mmsmhoagu4y2"
},
"path": "/t/interest-in-preprocessing-utilities-for-multifile-model-uploads/176211#post_2",
"publishedAt": "2026-05-27T02:57:09.000Z",
"site": "https://discuss.huggingface.co",
"tags": [
"“Don’t Repeat Yourself” / single model file policy",
"Add a model with Modular Transformers",
"cross-model imports violate the single-file policy",
"utils/modular_model_converter.py",
"dynamic_module_utils.py",
"Customizing models",
"trust_remote_code",
"Relative imports are quirky and not well documented",
"Relative path causes error when calling push_to_hub to upload a custom model",
"AutoModel.from_pretrained() doesn’t work for models with ‘.’ in their name when there’s a relative import",
"get_imports failing to respect conditionals on imports",
"modular_model_converter cannot handle objects import from try except"
],
"textContent": "I am personally not deeply familiar with this area, but this seems closely tied to the long-running Transformers discussion around the single-file philosophy:\n\n* * *\n\nYou may already be aware of this context, so apologies if this is redundant, but I think this proposal might be easier to evaluate if it is connected to the broader history of the Transformers **single-model-file policy** and the newer **Modular Transformers** compromise.\n\nMy understanding is roughly this:\n\n * Transformers has historically preferred a **single model file** style, where the code needed to understand a model’s forward pass lives in one `modeling_*.py` file.\n * This is intentionally not very DRY. The tradeoff is that model behavior is easier to inspect, review, copy, debug, and modify locally.\n * More recently, **Modular Transformers** seems to introduce a compromise: contributors can write a more modular source file with imports/inheritance, and a converter/linter generates standalone `modeling_*.py`, `configuration_*.py`, etc. files from it.\n * Your proposal feels like a similar pattern, but aimed at **Hub custom code / multifile model uploads** rather than models contributed directly to the Transformers repository.\n\n\n\nSome relevant background links:\n\n * Hugging Face design philosophy: “Don’t Repeat Yourself” / single model file policy\n * Current docs: Add a model with Modular Transformers\n * Modeling rules: cross-model imports violate the single-file policy\n * Converter implementation: utils/modular_model_converter.py\n * Dynamic module loading: dynamic_module_utils.py\n * Custom models docs: Customizing models\n * Auto classes / remote custom code docs: trust_remote_code\n\n\n\nSo perhaps the proposal could be framed not only as an isolated “inliner”, but as something like a **Hub-side analogue of Modular Transformers** :\n\n\n Transformers repo:\n modular_<model>.py\n -> generated modeling_<model>.py / configuration_<model>.py / processing_<model>.py\n\n Hub custom code:\n src/*.py or model/*.py\n -> generated flattened upload artifact\n\n\nThat framing might make the idea stronger, because it does not necessarily oppose the single-file philosophy. It could instead be seen as preserving the same final-user property:\n\n> authors can work with modular source code, while users/reviewers/loaders get a flattened, inspectable artifact.\n\nIn other words, the important question may not be “is flattening compatible with the single-file philosophy?” — it probably is, at least in spirit. The harder questions seem to be around **source of truth** , **reproducibility** , **semantic equivalence** , and **integration with the existing dynamic module loader**.\n\nA few design questions that seem important to me:\n\n 1. **What is the source of truth?**\nIs the multifile source tree the canonical code, with the flattened file treated as generated output? Or is the flattened file itself supposed to be edited/reviewed as the canonical Hub artifact?\n\n 2. **When is the flattened file generated?**\nShould it be generated locally before upload, by `save_pretrained`, by `push_to_hub`, by a Hub-side build step, or by a standalone CLI?\n\n 3. **Should the generated file be committed to the Hub repo?**\nCommitting it makes the actually executed code inspectable. But it also creates the risk that the generated file drifts from the source tree unless there is a check.\n\n 4. **Should there be a CI / pre-publish check?**\nFor example, something like: regenerate the flattened artifact, compare it with the committed one, and fail if they differ. This seems analogous to how generated files are checked in the Modular Transformers workflow.\n\n 5. **How do we verify semantic equivalence?**\nPython imports are not just textual inclusion. `try/except import`, optional dependencies, `TYPE_CHECKING`, module-level side effects, circular imports, `__all__`, lazy imports, and dynamically imported modules can all be tricky.\n\n 6. **How should this interact with`dynamic_module_utils.py`?**\nTransformers already has logic for discovering/copying relative imports in custom code. For example, `get_relative_import_files` recursively follows relative imports. A pre-flattening approach might reduce reliance on that mechanism, but it also overlaps with the same responsibility area.\n\n 7. **How should generated files be made reviewable?**\nIt may be useful for the flattened artifact to include clear source-file boundary markers, for example:\n\n\n\n\n\n # ---------------------------------------------------------------------\n # BEGIN inlined file: src/modeling/attention.py\n # ---------------------------------------------------------------------\n\n ...\n\n # ---------------------------------------------------------------------\n # END inlined file: src/modeling/attention.py\n # ---------------------------------------------------------------------\n\n\n 8. **Should generated files include a “do not edit manually” header?**\nSomething like:\n\n\n\n\n # This file is generated from the multifile source tree.\n # Do not edit this file manually; edit the source files and regenerate.\n\n\n 9. **Should the original multifile source be uploaded too?**\nUploading both the source tree and the flattened artifact may help reviewability, but it also raises the question of which one loaders should use.\n\n 10. **Should this be an external tool, a Transformers utility, or part of the Hub upload flow?**\nAn external tool is easier to experiment with. A Transformers utility might be easier to standardize. A Hub/upload integration would provide the best UX, but probably requires the clearest contract.\n\n\n\n\nI also think there is a useful distinction between two related but different problems:\n\n\n Problem A:\n How should models inside the Transformers repo be authored and maintained?\n\n Problem B:\n How should arbitrary custom model code on the Hub be packaged, loaded, cached, inspected, and trusted?\n\n\nModular Transformers seems primarily aimed at **Problem A**.\n\nYour proposal seems primarily aimed at **Problem B**.\n\nThat distinction makes the proposal more interesting, not less. It means this may not be a duplicate of Modular Transformers. It may be the same underlying compromise applied to a different layer of the ecosystem.\n\nThere are also some existing pain points around multifile custom code and relative imports that seem relevant:\n\n * Forum thread: Relative imports are quirky and not well documented\n * Older issue: Relative path causes error when calling push_to_hub to upload a custom model\n * Recent issue: AutoModel.from_pretrained() doesn’t work for models with ‘.’ in their name when there’s a relative import\n * Dynamic import edge case: get_imports failing to respect conditionals on imports\n * Modular converter edge case: modular_model_converter cannot handle objects import from try except\n\n\n\nThese examples make me think the hard part is not merely concatenating files. It is defining a small, predictable packaging contract for custom model code.\n\nOne possible contract could be something like:\n\n\n 1. The multifile source tree is the source of truth.\n 2. The flattened artifact is generated output.\n 3. The generated artifact is committed/uploaded for inspectability.\n 4. The generated artifact contains source-boundary comments.\n 5. The generated artifact contains a do-not-edit header.\n 6. A check verifies that the generated artifact is up to date.\n 7. A load test verifies that AutoModel.from_pretrained(..., trust_remote_code=True) works locally.\n 8. The tool explicitly documents unsupported Python patterns.\n\n\nThat kind of contract might make the tool easier to reason about, because it would avoid silently becoming a general-purpose Python bundler.\n\nFor example, it could explicitly support a conservative subset:\n\n\n Supported:\n - acyclic relative imports\n - same-repository Python source files\n - normal class/function/constant definitions\n - straightforward external imports\n - comments/docstrings preservation\n - source-file boundary markers\n\n Possibly unsupported or warning-only:\n - circular imports\n - wildcard imports\n - importlib-based dynamic imports\n - module-level side effects that depend on import order\n - optional imports inside complex conditionals\n - runtime mutation of module globals\n\n\nThis would also make the safety/review story clearer. A flattened file is not automatically safer than multifile code, especially with `trust_remote_code=True`, but it can make the review target more explicit if the generated file is deterministic and inspectable.\n\nSo my tentative reaction is:\n\n * The idea seems useful.\n * It seems philosophically compatible with the single-file policy if treated as “modular authoring → flattened artifact”.\n * It seems especially relevant for Hub custom code, where relative imports and dynamic module loading can be fragile.\n * The main challenge is not the basic inlining idea, but the contract around reproducibility, reviewability, semantic equivalence, and source-of-truth.\n * It might be worth explicitly positioning this as a **Hub/custom-code-side counterpart to Modular Transformers** , rather than only as a standalone preprocessing script.\n\n\n\nThis may also help decide where it should live. If the goal is experimentation, an external package seems natural. If the goal is standardizing custom-code packaging for the Hub, then it probably needs alignment with Transformers’ existing dynamic module loading and/or Hub upload APIs. If the goal is to eventually become official, it may be useful to first define the exact supported subset and failure modes.\n\nIn short, I like the direction, but I think the strongest framing is:\n\n> not “let’s replace the single-file philosophy,”\n> but “let’s give custom Hub model authors the same kind of modular-authoring / standalone-artifact compromise that Transformers itself is moving toward.”",
"title": "Interest in preprocessing utilities for multifile model uploads"
}