Skip to content

Proposal: Hugging Face Model Import #296

Description

@elliott-davis

Summary

Let users import a model from Hugging Face into a Harbor project as an OCI
model-spec (CNAI) artifact, with optional scheduled re-sync. You give a HF repo
slug (plus optional revision, subfolder, and token); Harbor resolves the model,
converts its files into a model-spec artifact, and stores it in a target
repository — so Harbor can be one governed registry for both images and models.

Background

Harbor already understands OCI model artifacts via the CNAI/model-spec processor
(model card, files, license, distinct artifact type). What's missing is a
supported on-ramp: getting a model from Hugging Face — the de facto hub for open
models — into Harbor today means an out-of-band "download, convert, push" loop.

That friction hurts three groups who want Harbor in this path: teams
standardizing on OCI model artifacts, air-gapped/regulated orgs that must pull
public models into a governed internal registry, and platform teams who'd rather
run one registry than a separate model store. This proposal makes the import a
native Harbor operation.

Proposal

A project-scoped Model Import capability:

  • Policy — a new project-scoped resource: HF repo ID, revision (default
    main), optional subfolder, target repo/tag, optional token, and a trigger
    that is manual or scheduled (cron).
  • Import job — a new MODEL_IMPORT jobservice job resolves the model via the
    HF API, streams each file, and assembles a model-spec OCI artifact (config plus
    per-file layers typed as weights/config/code/docs), pushes it, and tags it,
    reporting progress via check-ins.
  • Metadata & sync — captures model-card metadata (source URL, commit SHA,
    license, etc.) into the config; records the last imported commit SHA so
    repeated/scheduled runs are a no-op when upstream is unchanged.
  • Tokens — user-supplied HF tokens (for private/gated models) are stored
    encrypted at rest, used only by the job, and never returned by the API.
  • REST API — endpoints under /projects/{project_name}/model-import/… for
    policy CRUD, executions/tasks/logs, and a validate preview (resolve a
    repo/revision, preview file count and metadata) before importing. Authorized
    against the existing repository RBAC resource/actions.
  • Repository type (companion change) — a type field (IMAGE/MODEL) on
    the repository API and portal grid, derived from a repo's artifacts (any
    CNAI/model artifact ⇒ MODEL).
  • Portal UI — a guided "Import Model from Hugging Face" flow.

The source path (resolve → stream → convert → push) sits behind interfaces so
other sources can be added later, but Hugging Face is the only source here.

Non-Goals

  • Model serving/inference, and training/fine-tuning — import and governance only.
  • Sources other than Hugging Face (S3, MLflow, etc.) — the interfaces anticipate
    them; none are implemented here.
  • Exporting models back to Hugging Face — import is one-way.

Rationale

Why a dedicated subsystem instead of a Hugging Face replication adapter?
Replication moves existing OCI artifacts registry-to-registry; Hugging Face is a
Git-LFS model hub, not a registry. The core work here is converting a model's
files into a model-spec OCI artifact on the fly (typed layers + model-card
metadata) — a concept the adapter contract doesn't have and would be distorted
to add. A separate subsystem keeps model semantics explicit while reusing
Harbor's existing pieces (jobservice, scheduler, registry client, encryption,
repository RBAC) rather than adding parallel infrastructure.

Alternatives considered: a HF replication adapter (rejected — protocol mismatch
above); client-side/CLI tooling (rejected — leaves the governance gap that
motivates air-gapped/regulated users). Whether this should eventually converge
with replication is left as an Open Issue.

Compatibility

Additive only: a new model_import_policy table (forward migration), a new
MODEL_IMPORT vendor type, new endpoints, and a new optional repository type
field (defaults to IMAGE). Nothing existing changes. Imported artifacts are
standard model-spec artifacts handled by the existing CNAI processor, so
retention, quota, deletion, and display behave as usual. Requires jobservice
egress to Hugging Face (or a mirror in air-gapped setups), and builds on the
modelpack/model-spec libraries already used by CNAI.

Implementation

Implemented in an open PR against goharbor/harbor (backend under
pkg/modelimport, controller/modelimport, jobservice/job/impl/modelimport;
API/handlers; DB migration; portal UI; unit tests). I (@elliott-davis) will own
it through review and maintain it afterward. If smaller PRs are preferred, it can
split into: (1) import backend + API + migration, (2) scheduling/sync, (3) portal
UI, (4) repository type.

Open Issues

  • Scanning/signing. Scanners like Trivy don't inspect model weights, and
    provenance/signing for model artifacts is unsettled — what should Harbor
    assert beyond the upstream commit SHA and per-file digests?
  • Convergence with replication. Should model import eventually become a
    replication source, and if so, what would the adapter contract need to grow?

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions