goharbor / goharbor/community

Proposal: Hugging Face Model Import

Open
#296 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
No language data
Stars
82
Forks
92
PR merge metrics
No merged PRs in 30d

Description

## 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?

Contributor guide

Open the contributing guide

Research direction

Review the implementation paths named in the proposal: pkg/modelimport, controller/modelimport, jobservice/job/impl/modelimport, the API handlers, DB migration, and portal UI. Start by reviewing the existing open PR and unit tests; completion would cover the import backend, scheduling and sync, API and migration, repository type, and portal flow described here.

Written by the indexing model from the issue text.

Assessment

Tech stack
huggingface
Domain
api, backend, database, devops, frontend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
15/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.