Repository navigation
Conversation
Signed-off-by: chlins <chlins.zhang@gmail.com>
|
Something I don't see called out in this proposal is secrets management. Some models require the acceptance of a EULA and today their access is gated behind a users token that has accepted the EULA. Is there any effort to support these models in this proposal? |
|
Will this proposal make any attempt to differentiate model artifacts from container artifacts in a repository? A confused developer may try and pull one of these converted models expecting an engine to be packaged with it like a NVIDIA NIM and will experience a failure. |
elliott-davis
left a comment
There was a problem hiding this comment.
Overall this proposal aligns with what I would like to accomplish for model syncing in Harbor.
@elliott-davis Good question. Gated models are covered by the existing token mechanism rather than a new secrets subsystem: the user completes the EULA or license acceptance on the hub side with their own account beforehand, and the access token configured in Harbor's registry management (encrypted at rest) carries that entitlement. From Harbor's perspective this is plain token authentication when fetching; it implements no hub-specific consent flow. I've updated the Security Considerations section to make this explicit. |
@elliott-davis Yes. Converted models are model-spec OCI artifacts with their own artifactType and media types, so Harbor's UI can distinguish them from container images and will render them with a distinct icon, the same way charts, SBOMs, and signatures are differentiated today. On the pull path, however, both go through the standard Distribution v2 API, and the server should not intercept or reject pulls based on artifact type. So the safeguard is discoverability (distinct type and icon in the UI, plus the model-spec media types for tooling to inspect), not server-side gating; whether an artifact is runnable is up to the consuming tooling. |
Signed-off-by: chlins <chlins.zhang@gmail.com>
ebc6bbb to
bf76ea7
Compare
|
I don't think the claim that registry adapter won't work holds true, given the determinism the proposal already guarantees (Goal 4). If the packer turns a given revision plus file filters into a byte-identical manifest, the adapter isn't faking registry semantics. It derives them. The same packer could sit behind |
|
I think we still should strive for making it work with adapters, I think it will not only be easier to implement and maintain, but also for users to adapt and understand. The whole ecosystem in build around that too. cli, pulumi, tf proviers and all the scriptiin people has been made over the years. IMO it is worth reusing that. The adapter has policies, cron, executions, bandwidth limits, chunked resume and quota from replication, and pull-through from proxy cache via Now it is only Hugging Face what if other model source become availible and needed replication too and the same capabilities? It is not worth it, there no additional benifits in doing so. |
|
One good example where we failed to do it right in the first place, are the P2P preheat functionality. Harbor has 100lk deployments, theon only reported problem and users of this feature is the company who have made the PR. We never reecieve feature reqeuests, issues regarding that feature excapt from the original authors. and if it breaks it goes unnotices, until the origial team is migrating harbot to new version and notice that error. I don't want to repeat that again. |
|
To compare the two designs on running code, I opened a draft that takes the replication/proxy route: goharbor/harbor#24008. It adds a The adapter builds the manifest from the Hub API for a pinned commit, and the output is deterministic. One raw layer per file; LFS sha256 is the layer digest; non-LFS files are hashed and checked against their git blob id. The same commit always gives the same digest, so replication's digest comparison handles idempotence and no revision cursor is needed. Results on a dev Harbor with
Some points in this proposal hold up, and the PR says where:
Each can be added as a generic replication/registry extension that other adapters also benefit from, so none of them needs a parallel framework. The PR description lists the compromises I made and the Hub quirks that affect both designs, for example the anonymous 401 for missing models, case-sensitive Happy to fold anything from this proposal into that PR, or to work on it together with @chlins and @elliott-davis.
|
| - The `ArtifactRegistry` contract is manifest- and digest-addressed end to end (`PullManifest`, `PullBlob(repository, digest)`, `MountBlob`, ...). Model hubs have neither manifests nor universally digest-addressed content, so an adapter must fabricate registry semantics it cannot honor. | ||
| - Replication's idempotence compares source and destination digests of the *same* artifact. Model sync is a *conversion*: the source has no OCI digest, so the core skip/override semantics do not apply. | ||
| - An earlier proof-of-concept integrating Hugging Face through the replication adapter interface ran into these impedance mismatches directly ([KubeCon session](https://www.youtube.com/watch?v=0eiXSogHxmQ)). | ||
| - Harbor has removed a non-OCI upstream adapter before (ArtifactHub, together with the chartmuseum backend), which is a signal about the long-term cost of pretending non-OCI sources are registries. |
There was a problem hiding this comment.
The main reasons the ArtifactHub adapter was removed were its low-quality, buggy implementation and the upcoming OCI support.
There was a problem hiding this comment.
Fair point, I checked and it went out together with the chartmuseum backend in goharbor/harbor#18191, so it doesn't really say much about non-OCI sources. I'll drop that bullet.
|
|
||
| **2. Extending the OCI replication adapters.** Attractive on the surface: replication already has adapters, policies, filters, and triggers. It was rejected on evidence: | ||
|
|
||
| - The `ArtifactRegistry` contract is manifest- and digest-addressed end to end (`PullManifest`, `PullBlob(repository, digest)`, `MountBlob`, ...). Model hubs have neither manifests nor universally digest-addressed content, so an adapter must fabricate registry semantics it cannot honor. |
There was a problem hiding this comment.
https://github.com/llmmanorg/llmman is a good reference. llmman transfer hf.co/... builds a model-spec manifest straight from HF and streams it into the push without touching local disk.
There was a problem hiding this comment.
Thanks, didn't know about llmman. Streaming straight from HF is what we had in mind too, so this makes the PoC argument kind of outdated. I'll update that part.
|
Thanks for putting goharbor/harbor#24008 together, having running code to compare against is really helpful. Let me sync with @wy65701436 on the direction first, will come back here by next week. |
|
Thanks @Vad1mo and @chlins for putting together — having running code on both sides makes this a much better discussion. I’ve gone through both, Where I agree with:
Where I still think “separate” is right — but narrower than the proposal says
Proposed middle ground:
Does this split work for you? If there’s a reason the policy layer also has to be replication, I’d like to hear it, because that’s the one place I’m still choosing “separate”. |
|
One more structural point. Replication is symmetric by design: a policy has a src_registry and a dest_registry, either side can be the local Harbor, and the same adapter serves as source or target — Harbor-to-Harbor DR and multi-site is the whole reason it exists. Model Sync is strictly one-way: the source is always an external hub, the destination is always this Harbor, and there is no push direction — you can’t sync an OCI artifact back into a Hugging Face repo. Modeling that as a replication rule means a source-only capability flag, a UI that hides the type in the destination picker, a form full of greyed-out push/pull and namespace options, and an adapter where half the interface is MethodNotAllowed stubs. A dedicated Model Sync policy simply doesn’t have those fields: source → model → revision → destination repo. And the two features chain rather than overlap: Model Sync gets the model in, replication moves it between Harbors afterwards — exactly as it does for any other artifact. |


This pull request introduces a comprehensive proposal for a new Model Sync Adapter Framework in Harbor, aimed at enabling seamless synchronization of AI models from upstream model hubs (starting with Hugging Face) into Harbor as OCI artifacts. The framework is designed to be extensible, policy-driven, and deterministic, while reusing Harbor's proven architectural patterns without modifying the existing OCI replication system.
The most important changes are:
Framework Design and Architecture
fetch → convert → pushpipeline.Adapter Contract and Extensibility
resolve+stream) to make adding new model sources straightforward and maintainable, with Hugging Face as the reference implementation.Deterministic Packaging and Provenance
API, Data Model, and UI Integration