Actualités

Hugging Face à vendre pour 13 Md$ : sortir le Hub du chemin critique de vos builds et de vos pods

La presse tech rapporte que Hugging Face explore une cession valorisant l'entreprise à 13 Md$ ou plus. Au-delà du feuilleton financier, l'événement rappelle que des milliers de Dockerfile et d'initContainers appellent huggingface.co au build ou au démarrage. Cet article propose une méthode d'audit et trois niveaux de découplage, du pinning par SHA au packaging des poids en artefacts OCI signés.

| | | 9 min de lecture · par
Schéma d'un pipeline de déploiement de modèles reliant un registre d'artefacts à un cluster Kubernetes

Ce qui est rapporté, et ce qui n’est pas confirmé

Le 23 août 2026, Business Insider a révélé que Hugging Face explorait une cession, sur la base d’une valorisation évoquée à 13 milliards de dollars ou plus. L’information a été reprise le 24 août par TechCrunch, GuruFocus et l’essentiel de la presse tech. Selon ces mêmes sources, une banque a été mandatée pour sonder le marché.

Il faut être précis sur le statut du dossier, parce que la suite de cet article en dépend : aucun acquéreur n’est identifié publiquement, aucun accord n’est signé, et « explorer une cession » couvre un spectre large, du désengagement partiel d’investisseurs historiques à une acquisition pure. Le contexte connu ajoute une nuance intéressante : plus tôt cette année, la société avait décliné une offre d’investissement de 500 M$ de Nvidia sur une valorisation de 7 Md$, et Clem Delangue met régulièrement en avant la « soutenabilité long terme » de l’entreprise et sa quasi-rentabilité. Autrement dit, on n’est pas dans le scénario du fournisseur en détresse qui bradera son infrastructure la semaine prochaine.

Pour une équipe plateforme, la question n’est de toute façon pas boursière. Elle est beaucoup plus prosaïque : le Hub est devenu le registre de modèles de fait, et il se trouve dans le chemin critique de vos builds et de vos démarrages de pods. transformers, diffusers, sentence-transformers, vLLM, KServe, KAITO : tous savent résoudre un repo_id en poids téléchargés depuis huggingface.co. Un changement d’actionnaire, c’est potentiellement de nouvelles CGU, de nouveaux quotas, une tarification du stockage et de l’egress qui bouge, et — pour les charges européennes — une question de juridiction à reposer. La rumeur est un bon prétexte pour traiter une dette d’architecture que la plupart d’entre nous ont contractée sans y penser.

Cartographier son exposition en une heure

Avant toute décision, un inventaire. L’objectif est de lister tous les appels sortants vers huggingface.co, cdn-lfs*.huggingface.co et transfer.xethub.hf.co, et de savoir quand ils se produisent : au build, au démarrage du pod, ou pire, à la première requête utilisateur.

# 1. Résolutions de modèles dans le code et les images
rg -n --hidden -g '!.git' \
  -e 'from_pretrained\(' \
  -e 'snapshot_download|hf_hub_download' \
  -e 'huggingface-cli (download|login)|hf (download|auth)' \
  -e 'HF_TOKEN|HUGGING_FACE_HUB_TOKEN|HF_HOME|HF_ENDPOINT'

# 2. Les mêmes appels dans l'orchestration
rg -n -e 'huggingface' --glob '*.yaml' --glob '*.yml' --glob 'Dockerfile*' \
   charts/ manifests/ .github/ .gitlab-ci.yml

# 3. Les initContainers qui téléchargent des poids
kubectl get pods -A -o json \
  | jq -r '.items[] | select(.spec.initContainers != null)
           | [.metadata.namespace, .metadata.name,
              (.spec.initContainers[].args // [] | join(" "))] | @tsv' \
  | grep -i -e hugging -e snapshot_download -e 'hf download'

Complétez par la relecture des logs d’egress du proxy sortant sur 30 jours (volumes par domaine, pics corrélés aux déploiements) et par un inventaire des NetworkPolicy : si vos namespaces d’inférence ont un egress 0.0.0.0/0, vous ne mesurez rien. Deux points d’attention souvent oubliés : les modèles gated (Llama, certains modèles Mistral, plusieurs datasets), dont l’accès dépend d’une acceptation de licence liée à un compte, et les tokens personnels stockés en secret CI. Un token nominatif dans un secret partagé, c’est un SPOF humain avant d’être un problème de gouvernance.

Quatre risques concrets, indépendants du repreneur

  1. CGU et conditions d’accès. Les licences des modèles ne changent pas avec l’actionnaire, mais les conditions d’accès à la plateforme, oui : authentification obligatoire pour les téléchargements anonymes, restrictions sur l’usage automatisé, plafonnement des tokens de service.
  2. Quotas, bande passante et facturation. Le backend de stockage Xet, avec sa déduplication par chunks, change le profil des transferts. Toute évolution tarifaire sur le stockage ou l’egress se répercute directement sur des équipes qui téléchargent le même modèle de 30 Go à chaque scale-out.
  3. Disparition ou dépriorisation de repos. C’est déjà la réalité aujourd’hui, sans aucune acquisition : un auteur renomme son organisation, transforme un repo public en privé, retire un dataset après une mise en demeure. Votre main d’hier n’existe plus.
  4. Localisation et conformité. Pour une charge soumise à des exigences de souveraineté, « je récupère mes artefacts de production chez un tiers américain, au runtime, sans copie interne » est une phrase difficile à défendre en comité d’architecture.

Niveau 1 — arrêter de builder contre Internet

Le premier niveau ne coûte presque rien et élimine la majorité des incidents. Trois règles.

Épingler par SHA de commit, jamais main. Un tag est mutable, une branche encore plus.

from transformers import AutoModel, AutoTokenizer

REPO = "sentence-transformers/all-MiniLM-L6-v2"
REV  = "c9745ed1d9f207416be6d2e6f8de32d1f16199bf"  # commit SHA, immuable

tok   = AutoTokenizer.from_pretrained(REPO, revision=REV)
model = AutoModel.from_pretrained(REPO, revision=REV)

Pré-hydrater le cache au build, verrouiller le runtime. Le téléchargement appartient à l’étape de build, pas au démarrage du pod. On sépare donc explicitement les deux, et on refuse tout accès réseau à l’exécution.

# ---- étape de build : seule étape autorisée à sortir sur Internet
FROM python:3.12-slim AS fetch
ARG HF_TOKEN
ENV HF_HOME=/opt/hf
RUN pip install --no-cache-dir "huggingface_hub[hf_transfer]==0.35.*"
RUN --mount=type=secret,id=hf_token \
    HF_TOKEN="$(cat /run/secrets/hf_token)" \
    HF_HUB_ENABLE_HF_TRANSFER=1 \
    hf download sentence-transformers/all-MiniLM-L6-v2 \
      --revision c9745ed1d9f207416be6d2e6f8de32d1f16199bf \
      --include "*.safetensors" "*.json" "tokenizer*" \
      --exclude "*.bin" "*.h5" "*.msgpack"

# ---- image de runtime : hors ligne par construction
FROM python:3.12-slim
COPY --from=fetch /opt/hf /opt/hf
ENV HF_HOME=/opt/hf \
    HF_HUB_OFFLINE=1 \
    HF_HUB_DISABLE_TELEMETRY=1
COPY app/ /app/
CMD ["python", "/app/serve.py"]

Tester le démarrage réseau coupé, en CI. C’est la seule façon de détecter les bibliothèques qui n’honorent pas le cache. Les wrappers de haut niveau (frameworks d’embeddings, SDK d’agents, certains loaders ONNX — fastembed est un cas régulièrement cité) implémentent parfois leur propre répertoire de cache et ignorent HF_HOME ou HF_HUB_OFFLINE. Le symptôme est toujours le même : l’image fonctionne sur le poste du développeur et échoue au premier pod planifié dans un namespace correctement cloisonné.

docker run --rm --network none \
  -e HF_HUB_OFFLINE=1 \
  monorg/inference:1.4.2 python -c "import app.serve as s; s.warmup()"

À l’échelle du cluster, la contrepartie est une NetworkPolicy d’egress restrictive sur les namespaces d’inférence : si un pod tente encore de joindre le Hub, on veut un échec bruyant en préproduction, pas un téléchargement silencieux de 20 Go en production.

Niveau 2 — un miroir maîtrisé

Le pinning ne résout pas le cas des équipes de recherche qui itèrent sur des dizaines de modèles par semaine. Là, on interpose un cache. huggingface_hub respecte HF_ENDPOINT, ce qui rend l’opération quasi transparente côté client.

export HF_ENDPOINT=https://hf-cache.interne.example.com
export HF_HUB_DISABLE_XET=1

Côté serveur, deux familles de solutions : des proxys cache dédiés open source (Olah, dingospeed, ou les déploiements de type hf-mirror) et les gestionnaires d’artefacts d’entreprise dont les dépôts « remote » savent proxifier du HTTP générique. Trois points de dimensionnement à ne pas négliger :

  • Désactiver Xet côté client (HF_HUB_DISABLE_XET=1) peut être un choix rationnel : votre cache amont dédupliquera très mal des chunks qu’il ne comprend pas, alors qu’il gère parfaitement des fichiers LFS classiques adressés par URL stable. On échange une partie de l’efficacité de transfert contre une efficacité de cache et une empreinte de stockage prévisible.
  • Purge et volumétrie : un miroir de modèles grossit vite. LRU avec plancher sur une liste de modèles « pinnés » par les équipes produit, et un quota par organisation.
  • TLS et authentification : le miroir devient le porteur des tokens d’accès aux repos gated. Il doit donc être authentifié (OIDC de la plateforme), journalisé, et surtout ne jamais servir de tunnel anonyme vers l’extérieur.

Niveau 3 — vos modèles comme artefacts OCI

Le niveau le plus abouti consiste à traiter les poids comme n’importe quel autre artefact de build : un objet immuable, signé, dans votre registre. ORAS et KitOps permettent de packager un modèle en artefact OCI ; KServe (modelcars) et KAITO savent monter des images de modèles.

# Packaging avec ORAS
oras push registry.interne.example.com/models/all-minilm-l6-v2:c9745ed \
  --artifact-type application/vnd.model.v1+json \
  model.safetensors:application/octet-stream \
  tokenizer.json:application/json \
  config.json:application/json

# Signature et provenance
cosign sign registry.interne.example.com/models/all-minilm-l6-v2:c9745ed
cosign attest --predicate provenance.json \
  registry.interne.example.com/models/all-minilm-l6-v2:c9745ed
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
  name: minilm
spec:
  predictor:
    model:
      modelFormat: {name: huggingface}
      storageUri: oci://registry.interne.example.com/models/all-minilm-l6-v2:c9745ed

Le gain est net : mêmes RBAC, mêmes scanners, même réplication géographique, même GitOps que pour vos images applicatives, et une politique d’admission (Kyverno, Ratify) qui refuse tout modèle non signé. La perte est réelle aussi, et il faut l’assumer : vous perdez les métadonnées du Hub, les model cards, l’historique des discussions et la découverte. Le registre OCI est un excellent véhicule de distribution ; ce n’est pas un catalogue. Prévoyez d’exporter la model card et la licence dans l’artefact, sous peine de ne plus savoir dans six mois sous quelles conditions vous servez ce modèle.

Sécuriser la chaîne au passage

Le rapatriement est l’occasion d’imposer ce qui aurait dû l’être depuis longtemps : refus des formats picklés (.bin, .pt, .pkl, .msgpack) au profit de safetensors, dont le format ne permet pas l’exécution de code arbitraire au chargement ; vérification systématique des empreintes avant mise en cache ; scan des repos entrants (picklescan, analyse antivirale, détection de secrets) ; et journalisation exploitable du couple « pod → SHA de modèle chargé ». Cette dernière ligne est ce qui vous permettra, le jour où un repo amont est retiré pour cause de licence contestée, de répondre en dix minutes à la question « qui l’utilise en production ? ».

Grille de décision et plan à 30 jours

Classez vos modèles en trois catégories. Figés : les modèles de production stables, épinglés au SHA et embarqués dans l’image — coût de stockage marginal, temps de démarrage optimal, zéro dépendance externe. Miroités : le catalogue exploratoire, servi par le cache interne — coût de stockage modéré, egress amortie. Rapatriés en OCI : les modèles critiques, réglementés, ou fine-tunés en interne — coût opérationnel plus élevé, mais souveraineté et traçabilité complètes.

Sur trente jours : semaine 1, l’inventaire et la métrologie de l’egress ; semaine 2, le pinning par SHA et le test réseau coupé en CI sur tous les services d’inférence ; semaine 3, le miroir HF_ENDPOINT en préproduction ; semaine 4, deux ou trois modèles critiques en OCI signé, avec la politique d’admission associée. Les indicateurs à suivre sont peu nombreux : octets sortants vers les domaines Hugging Face par semaine, p95 du temps de démarrage à froid des pods d’inférence, part des services validés en mode offline, nombre de références mutables (main, tags) restantes.

Une précision, pour finir, sur le périmètre : normaliser HF_HOME, HF_HUB_OFFLINE, HF_HUB_DISABLE_XET et HF_ENDPOINT dans vos images de base, épingler des SHA et exiger safetensors — ce sont quelques jours de travail. Reconstruire un catalogue de modèles interne, avec évaluation, versioning sémantique et gouvernance, c’est un projet de plusieurs trimestres. Ne pas confondre les deux est probablement la décision d’architecture la plus rentable de ce dossier.

Quel que soit le sort de la rumeur du 23 août, la leçon reste la même que celle de left-pad ou du rate limiting de Docker Hub : une dépendance gratuite, pratique et non contractualisée finit toujours par se rappeler à vous, et rarement au bon moment. Le Hub est un formidable point de distribution ; il ne devrait jamais être un point de défaillance unique dans un readinessProbe. Que Hugging Face reste indépendant ou change de main, un docker run --network none qui passe en CI est un excellent investissement.

Commentaires (0)

Veuillez vous connecter pour laisser un commentaire.

Se connecter

Pas encore de commentaires. Soyez le premier à commenter !