Hub Python Library documentation
Subir archivos al Hub
Subir archivos al Hub
Compartir tus archivos y tu trabajo es un aspecto importante del Hub. La librería huggingface_hub ofrece varias opciones para subir tus archivos al Hub. Puedes usar estas funciones de forma independiente o integrarlas en tu librería, lo que facilita a tus usuarios la interacción con el Hub.
Cada vez que quieras subir archivos al Hub, necesitas iniciar sesión en tu cuenta de Hugging Face. Para más detalles sobre la autenticación, consulta esta sección.
Subir un archivo
Una vez que hayas creado un repositorio con create_repo(), puedes subir un archivo a tu repositorio usando upload_file().
Especifique la ruta del archivo a cargar, el lugar del repositorio donde desea cargarlo y el nombre del repositorio al que desea agregar el archivo. Dependiendo del tipo de su repositorio, puede establecer opcionalmente el tipo de repositorio como dataset, model o space.
>>> from huggingface_hub import HfApi
>>> api = HfApi()
>>> api.upload_file(
... path_or_fileobj="/path/to/local/folder/README.md",
... path_in_repo="README.md",
... repo_id="username/test-dataset",
... repo_type="dataset",
... )Subir una carpeta
Use la función upload_folder() para subir una carpeta local a un repositorio existente. Especifique la ruta de la carpeta local a subir, dónde desea subirla dentro del repositorio y el nombre del repositorio al que desea añadir la carpeta. Dependiendo del tipo de su repositorio, puede configurar opcionalmente el tipo de repositorio como dataset, model o space.
>>> from huggingface_hub import HfApi
>>> api = HfApi()
# Upload all the content from the local folder to your remote Space.
# By default, files are uploaded at the root of the repo
>>> api.upload_folder(
... folder_path="/path/to/local/space",
... repo_id="username/my-cool-space",
... repo_type="space",
... )Por defecto, el archivo .gitignore se tiene en cuenta para saber qué archivos deben o no ser incluidos en el commit. Por defecto, comprobamos si hay un archivo .gitignore en un commit y, si no, comprobamos si existe en el Hub. Tenga en cuenta que solo se utilizará un archivo .gitignore presente en la raíz del directorio. No comprobamos archivos .gitignore en subdirectorios.
Si no desea usar un archivo .gitignore hardcodeado, puede usar los argumentos allow_patterns y ignore_patterns para filtrar qué archivos se suben. Estos parámetros aceptan un solo patrón o una lista de patrones. Los patrones son comodines estándar (patrones de globbing) tal como se documenta aquí. Si se proporcionan tanto allow_patterns como ignore_patterns, se aplican ambas restricciones.
Además del archivo .gitignore y de los patrones de permitir/ignorar, cualquier carpeta .git/ presente en cualquier subdirectorio se ignorará.
>>> api.upload_folder(
... folder_path="/path/to/local/folder",
... path_in_repo="my-dataset/train", # Upload to a specific folder
... repo_id="username/test-dataset",
... repo_type="dataset",
... ignore_patterns="**/logs/*.txt", # Ignore all text logs
... )También puede usar el argumento delete_patterns para especificar los archivos que desea eliminar del repositorio en el mismo commit.
Esto puede resultar útil si desea limpiar una carpeta remota antes de enviar archivos a ella y no sabe qué archivos
ya existen.
El siguiente ejemplo sube la carpeta local ./logs a la carpeta remota /experiment/logs/. Solo se suben los archivos txt, pero antes se eliminan todos los registros anteriores del repositorio. Todo esto en un solo commit.
>>> api.upload_folder(
... folder_path="/path/to/local/folder/logs",
... repo_id="username/trained-model",
... path_in_repo="experiment/logs/",
... allow_patterns="*.txt", # Upload all local text files
... delete_patterns="*.txt", # Delete all remote text files before
... )Cómo se suben los archivos
Cuando hf_xet está instalado (que es el caso por defecto), upload_folder() sube archivos a través de una canalización en streaming: los archivos se comprueban contra el Hub, se suben al backend de almacenamiento Xet (que realiza el troceado, la deduplicación y los reintentos de transferencia internamente) y se confirman en lotes adaptativos, todo en paralelo. En la práctica, esto significa:
- Carpetas de cualquier tamaño: las carpetas pequeñas se suben en un solo commit, mientras que las carpetas con muchos archivos se dividen automáticamente en varios commits para no superar los límites del servidor. Cuando esto ocurre, los commits posteriores reciben un sufijo
(part 2),(part 3), … en el mensaje del commit. - Reanudable: si la carga se interrumpe por cualquier motivo, simplemente vuelve a ejecutar la misma llamada. Los archivos ya comprometidos se detectan y se omiten, y los fragmentos ya cargados se deduplican: volver a cargarlos transfiere (casi) ningún dato. No se involucra ningún estado local: incluso puedes reanudar desde una máquina diferente. Una excepción: con
create_pr=True, volver a ejecutar abre una nueva solicitud de extracción. Recomendamos volver a ejecutar conrevision="refs/pr/N"en su lugar al reanudar la carga. - Sin doble lectura: los archivos se hashean mientras se dividen en fragmentos para la carga, en una sola pasada de lectura. No hay una fase de “hashing” separada antes de que comience la carga.
Una visualización de progreso en vivo sigue las tres etapas:
Found 5,000 files to upload
Preparing ████████████████████ 5,000 / 5,000 ✓
Uploading ██████████████░░░░░░ 423 / 603 files 3.8GB · 19.7MB/s
Committing ██████████████████░░ 4,580 / 5,000 6 commitsSi hf_xet no está instalado, upload_folder() recurre al comportamiento anterior: primero calcula el hash de todo, sube por HTTP y luego crea un único commit. Siempre recomendamos mantener hf_xet instalado para una mayor robustez
Subir desde la CLI
Puede usar el comando hf upload desde la terminal para subir archivos directamente al Hub. Internamente, utiliza los mismos helpers upload_file() y upload_folder() descritos anteriormente.
Puedes subir un solo archivo o una carpeta completa:
# Usage: hf upload [repo_id] [local_path] [path_in_repo]
>>> hf upload Wauplin/my-cool-model ./models/model.safetensors model.safetensors
https://huggingface.co/Wauplin/my-cool-model/blob/main/model.safetensors
>>> hf upload Wauplin/my-cool-model ./models .
https://huggingface.co/Wauplin/my-cool-model/tree/mainlocal_path y path_in_repo son opcionales y se pueden inferir implícitamente. Si local_path no está definido, la herramienta
comprobará si existe una carpeta o archivo local con el mismo nombre que repo_id. En ese caso, se subirá su contenido.
De lo contrario, se lanzará una excepción que pide al usuario definir explícitamente local_path. En cualquier caso, si path_in_repo no está
definido, los archivos se suben en la raíz del repositorio.
El destino también se puede expresar como un único URI hf:// que sigue la gramática hf://[<TYPE>/]<ID>[@<REVISION>][/<PATH>] (consulte la referencia de URIs de HF para la sintaxis completa). El tipo de repositorio, la revisión y path_in_repo se leen entonces del URI, que no se puede combinar con las opciones --repo-type y --revision:
# Upload a single file to a dataset on a specific branch
>>> hf upload hf://datasets/Wauplin/my-cool-dataset@my-branch/data/train.csv ./train.csv
https://huggingface.co/datasets/Wauplin/my-cool-dataset/blob/my-branch/data/train.csvPara obtener el máximo rendimiento de subida en archivos grandes, establezca la variable de entorno
HF_XET_HIGH_PERFORMANCE=1. Esto activa el modo de alto rendimiento dehf_xet, que satura la banda ancha y los núcleos de CPU disponibles. Nota: la bandera legadaHF_HUB_ENABLE_HF_TRANSFER=1ya no se utiliza, ya quehf_transferse eliminó en favor dehf_xet; establezcaHF_XET_HIGH_PERFORMANCE=1en su lugar.
Para más detalles sobre el comando de carga de la CLI, consulte la guía de la CLI.
Subir una carpeta grande
upload_folder() y el comando hf upload son las soluciones recomendadas para subir archivos al Hub, incluso para carpetas muy grandes. Los archivos se transmiten al Hub en varios commits y el proceso se reanuda automáticamente si se interrumpe. Simplemente vuelve a ejecutar la misma llamada y los archivos ya subidos se omiten.
>>> api.upload_folder(
... repo_id="HuggingFaceM4/Docmatix",
... repo_type="dataset",
... folder_path="/path/to/local/docmatix",
... )o desde la terminal:
hf upload HuggingFaceM4/Docmatix --repo-type=dataset /path/to/local/docmatix
Consejos y trucos para cargas grandes
Hay algunas limitaciones que conviene tener en cuenta al trabajar con grandes cantidades de datos en tu repositorio. Dado el tiempo que tarda en transmitirse los datos, que una carga o un push falle al final del proceso, o que la experiencia se degrade, ya sea en hf.co o al trabajar localmente, puede resultar muy molesto.
Consulta nuestra guía Limitaciones y recomendaciones del repositorio para conocer las mejores prácticas sobre cómo estructurar tus repositorios en el Hub. Pasemos a algunos consejos prácticos para que tu proceso de carga sea lo más fluido posible.
- Empieza por poco: Recomendamos comenzar con una pequeña cantidad de datos para probar tu script de carga. Es más fácil iterar sobre un script cuando un fallo solo toma un poco de tiempo.
- Espera fallos: Transmitir grandes cantidades de datos es un desafío. No sabes qué puede pasar, pero siempre es mejor considerar que algo fallará al menos una vez, ya sea por tu máquina, tu conexión o nuestros servidores. Por ejemplo, si planeas subir un gran número de archivos, es mejor llevar un registro local de qué archivos ya subiste antes de subir el siguiente lote. Se garantiza que un archivo LFS que ya está comprometido nunca se volverá a subir dos veces, pero verificarlo en el lado del cliente aún puede ahorrar tiempo. Esto es lo que upload_folder() hace por ti.
- Usar
hf_xet: esta opción aprovecha el nuevo backend de almacenamiento del Hub, está escrita en Rust y ya está disponible para todos. De hecho,hf_xetya está habilitado de forma predeterminada al usarhuggingface_hub!. Para obtener el máximo rendimiento, estableceHF_XET_HIGH_PERFORMANCE=1como variable de entorno. Ten en cuenta que, cuando el modo de alto rendimiento está habilitado, la herramienta intentará usar toda la banda ancha y los núcleos de CPU disponibles.
Funciones avanzadas
En la mayoría de los casos, no necesitarás más que upload_file() y upload_folder() para subir tus archivos al Hub.
Sin embargo, huggingface_hub cuenta con funciones más avanzadas para facilitar las cosas. ¡Echemos un vistazo!
Subidas más rápidas
Aprovecha las cargas más rápidas mediante hf_xet, el enlace de Python para la biblioteca xet-core que permite la deduplicación basada en fragmentos para cargas y descargas más rápidas. hf_xet se integra a la perfección con huggingface_hub, pero utiliza la biblioteca Rust xet-core y el almacenamiento Xet en lugar de LFS.
hf_xet utiliza el sistema de almacenamiento Xet, que divide los archivos en fragmentos inmutables, almacena colecciones de estos fragmentos (llamados bloques o xorbs) de forma remota y los recupera para reensamblar el archivo cuando se solicita. Al subir, después de confirmar que el usuario está autorizado para escribir en este repositorio, hf_xet analizará los archivos, los dividirá en sus fragmentos y agrupará dichos fragmentos en xorbs (y deduplicará entre fragmentos conocidos), y luego subirá estos xorbs al servicio de direccionamiento por contenido (CAS) de Xet, que verificará la integridad de los xorbs, registrará los metadatos de los xorbs junto con el hash SHA256 de LFS (para soportar la búsqueda/descarga) y escribirá los xorbs en el almacenamiento remoto.
Para habilitarlo, simplemente instala la última versión de huggingface_hub:
pip install -U "huggingface_hub"A partir de huggingface_hub 0.32.0, esto también instalará hf_xet.
Todas las demás APIs de huggingface_hub seguirán funcionando sin ninguna modificación. Para conocer más sobre los beneficios del almacenamiento Xet y hf_xet, consulte esta sección.
Consideraciones para la carga en un clúster / sistema de archivos distribuido
Al subir archivos desde un clúster, los archivos que se están subiendo suelen residir en un sistema de archivos distribuido o de red (NFS, EBS, Lustre, Fsx, etc.). El almacenamiento Xet dividirá esos archivos en fragmentos y los escribirá en bloques (también llamados xorbs) localmente, y una vez que el bloque esté completo, los subirá. Para un mejor rendimiento al subir desde un sistema de archivos distribuido, asegúrese de establecer HF_XET_CACHE en un directorio que esté en un disco local (por ejemplo, un disco NVMe o SSD local). La ubicación predeterminada para la caché de Xet está bajo HF_HOME en (~/.cache/huggingface/xet) y, al estar en el directorio de inicio del usuario, a menudo también se encuentra en el sistema de archivos distribuido.
Subidas no bloqueantes
En algunos casos, deseas enviar datos sin bloquear tu hilo principal. Esto resulta especialmente útil para subir registros y artefactos mientras continúas un entrenamiento. Para ello, puedes utilizar el argumento run_as_future tanto en upload_file() como en upload_folder(). Esto devolverá un objeto concurrent.futures.Future que puedes usar para verificar el estado de la subida.
>>> from huggingface_hub import HfApi
>>> api = HfApi()
>>> future = api.upload_folder( # Upload in the background (non-blocking action)
... repo_id="username/my-model",
... folder_path="checkpoints-001",
... run_as_future=True,
... )
>>> future
Future(...)
>>> future.done()
False
>>> future.result() # Wait for the upload to complete (blocking action)
...Las tareas en segundo plano se encolan cuando se usa
run_as_future=True. Esto significa que se garantiza que las tareas se ejecutarán en el orden correcto.
Aunque las tareas en segundo plano son útiles principalmente para subir datos/crear commits, puedes encolar cualquier método que desees usando run_as_future(). Por ejemplo, puedes usarlo para crear un repositorio y luego subir datos a él en segundo plano. El argumento run_as_future integrado en los métodos de subida es simplemente un alias para ello.
>>> from huggingface_hub import HfApi
>>> api = HfApi()
>>> api.run_as_future(api.create_repo, "username/my-model", exists_ok=True)
Future(...)
>>> api.upload_file(
... repo_id="username/my-model",
... path_in_repo="file.txt",
... path_or_fileobj=b"file content",
... run_as_future=True,
... )
Future(...)Copiar archivos entre repositorios
Use copy_files() para copiar archivos o carpetas entre repositorios en el Hub sin descargar ni volver a subir grandes cantidades de datos. Esto es útil cuando desea duplicar pesos entre variantes de modelos, copiar archivos de conjuntos de datos entre repositorios o reorganizar archivos entre sus repositorios. Internamente, crea un commit con operaciones de CommitOperationCopy.
>>> from huggingface_hub import HfApi
>>> api = HfApi()
# Copy a single file between repos
>>> api.copy_files(
... "hf://username/source-model/weights.safetensors",
... "hf://username/target-model/weights.safetensors",
... )
# Copy an entire folder
>>> api.copy_files(
... "hf://datasets/username/source-dataset/data/",
... "hf://datasets/username/target-dataset/data/",
... )También puede copiar dentro del mismo repositorio:
# Duplicate a file in the same repo
>>> api.copy_files(
... "hf://username/my-model/config.json",
... "hf://username/my-model/backup/config.json",
... )Al copiar una carpeta, una barra final
/en la fuente utiliza semánticas de estilo rsync, lo que significa que se copian los contenidos de la carpeta, sin anidar la propia carpeta. Sin una barra final/, la propia carpeta se anida en el destino.
copy_files() también permite copiar archivos a Buckets. Consulte la guía de Buckets para obtener más detalles.
Subidas programadas
El Hugging Face Hub facilita guardar y versionar datos. Sin embargo, existen algunas limitaciones al actualizar el mismo archivo miles de veces. Por ejemplo, es posible que desees guardar los registros de un proceso de entrenamiento o la retroalimentación de los usuarios sobre un Space desplegado. En estos casos, tiene sentido subir los datos como un dataset en el Hub, pero puede ser difícil hacerlo de manera adecuada. La razón principal es que no deseas versionar cada actualización de tus datos, ya que eso haría que el repositorio de git sea inutilizable. La clase CommitScheduler ofrece una solución a este problema.
La idea es ejecutar una tarea en segundo plano que suba periódicamente una carpeta local al Hub. Supongamos que tienes un Espacio de Gradio que toma como entrada un texto y genera dos traducciones de este. Luego, el usuario puede seleccionar su traducción preferida. Para cada ejecución, deseas guardar la entrada, la salida y la preferencia del usuario para analizar los resultados. Este es un caso de uso perfecto para CommitScheduler; quieres guardar datos en el Hub (posiblemente millones de comentarios de usuarios), pero no necesitas guardar en tiempo real la entrada de cada usuario. En su lugar, puedes guardar los datos localmente en un archivo JSON y subirlos cada 10 minutos. Por ejemplo:
>>> import json
>>> import uuid
>>> from pathlib import Path
>>> import gradio as gr
>>> from huggingface_hub import CommitScheduler
# Define the file where to save the data. Use UUID to make sure not to overwrite existing data from a previous run.
>>> feedback_file = Path("user_feedback/") / f"data_{uuid.uuid4()}.json"
>>> feedback_folder = feedback_file.parent
# Schedule regular uploads. Remote repo and local folder are created if they don't already exist.
>>> scheduler = CommitScheduler(
... repo_id="report-translation-feedback",
... repo_type="dataset",
... folder_path=feedback_folder,
... path_in_repo="data",
... every=10,
... )
# Define the function that will be called when the user submits its feedback (to be called in Gradio)
>>> def save_feedback(input_text:str, output_1: str, output_2:str, user_choice: int) -> None:
... """
... Append input/outputs and user feedback to a JSON Lines file using a thread lock to avoid concurrent writes from different users.
... """
... with scheduler.lock:
... with feedback_file.open("a") as f:
... f.write(json.dumps({"input": input_text, "output_1": output_1, "output_2": output_2, "user_choice": user_choice}))
... f.write("\n")
# Start Gradio
>>> with gr.Blocks() as demo:
>>> ... # define Gradio demo + use `save_feedback`
>>> demo.launch()¡Y eso es todo! Las entradas/salidas del usuario y los comentarios estarán disponibles como un conjunto de datos en el Hub. Al usar un nombre de archivo JSON único, se garantiza que no sobrescribirá datos de una ejecución anterior ni datos de otros Spaces/replicas que envíen datos de forma concurrente al mismo repositorio.
Para más detalles sobre el CommitScheduler, esto es lo que necesita saber:
- solo de adición: Se asume que solo añadirás contenido a la carpeta. Debes añadir datos a los archivos existentes o crear archivos nuevos. Eliminar o sobrescribir un archivo podría corromper tu repositorio.
- historial de git:
El programador enviará el contenido de la carpeta cada
everyminutos. Para evitar saturar demasiado el repositorio de git, se recomienda establecer un valor mínimo de 5 minutos. Además, el programador está diseñado para evitar envíos vacíos. Si no se detecta nuevo contenido en la carpeta, se descarta el envío programado. - errors: El programador se ejecuta como un hilo en segundo plano. Se inicia al instanciar la clase y se mantiene en ejecución hasta que se llama a
stop()o el proceso termina. Si ocurre un error durante la carga (por ejemplo, un problema de conexión), el error se registra en el registro y el programador reintenta en el siguiente compromiso programado. - scripts: En un script con una vida útil acotada (p. ej., entrenamiento), usa el programador como un gestor de contexto. Al salir del bloque
withse realiza una última carga, se espera a que se complete y se detiene el programador. - seguridad de hilos: En la mayoría de los casos, es seguro asumir que puede escribir en un archivo sin preocuparse por un archivo de bloqueo. El programador no se bloqueará ni se corruptará si escribe contenido en la carpeta mientras está subiendo. En la práctica, es posible que ocurran problemas de concurrencia en aplicaciones con mucha carga. En este caso, aconsejamos usar el bloqueo
scheduler.lockpara garantizar la seguridad de hilos. El bloqueo solo se activa cuando el programador escanea la carpeta en busca de cambios, no cuando sube datos. Puede asumir con seguridad que no afectará la experiencia de usuario en su Space.
Demostración de persistencia de espacio
Persistir datos de un Space en un Dataset del Hub es el caso de uso principal de CommitScheduler. Dependiendo del caso de uso, es posible que desees estructurar tus datos de manera diferente. La estructura debe ser robusta ante usuarios concurrentes y reinicios, lo que a menudo implica generar UUIDs. Además de la robustez, debes subir los datos en un formato legible por la biblioteca 🤗 Datasets para su reutilización posterior. Creamos un Space que demuestra cómo guardar varios formatos de datos diferentes (es posible que necesites adaptarlo a tus necesidades específicas).
Subidas personalizadas
CommitScheduler asume que tus datos son solo de adición y que deben subirse “tal cual”. Sin embargo, es posible que quieras personalizar la forma en que se suben los datos. Puedes hacerlo creando una clase que herede de CommitScheduler y sobrescribiendo el método push_to_hub (puedes sobrescribirlo de la manera que prefieras). Se garantiza que se llamará cada every minutos en un hilo en segundo plano. No tienes que preocuparte por la concurrencia ni por los errores, pero debes tener cuidado con otros aspectos, como hacer commits vacíos o duplicar datos.
En el ejemplo (simplificado) siguiente, sobrescribimos push_to_hub para comprimir todos los archivos PNG en un único archivo y evitar sobrecargar el repositorio en el Hub:
class ZipScheduler(CommitScheduler):
def push_to_hub(self):
# 1. List PNG files
png_files = list(self.folder_path.glob("*.png"))
if len(png_files) == 0:
return None # return early if nothing to commit
# 2. Zip png files in a single archive
with tempfile.TemporaryDirectory() as tmpdir:
archive_path = Path(tmpdir) / "train.zip"
with zipfile.ZipFile(archive_path, "w", zipfile.ZIP_DEFLATED) as zip:
for png_file in png_files:
zip.write(filename=png_file, arcname=png_file.name)
# 3. Upload archive
self.api.upload_file(..., path_or_fileobj=archive_path)
# 4. Delete local png files to avoid re-uploading them later
for png_file in png_files:
png_file.unlink()Cuando sobrescribes push_to_hub, tienes acceso a los atributos de CommitScheduler y, en particular, a:
- Cliente HfApi:
api - Parámetros de carpeta:
folder_pathypath_in_repo - Parámetros del repositorio:
repo_id,repo_type,revision - El bloqueo de hilo:
lock
Para más ejemplos de programadores personalizados, consulte nuestro espacio de demostración que contiene diferentes implementaciones según sus casos de uso.
create_commit
Las funciones upload_file() y upload_folder() son APIs de alto nivel que resultan generalmente convenientes de usar. Recomendamos probar estas funciones primero si no necesitas trabajar a un nivel inferior. Sin embargo, si deseas trabajar a nivel de commit, puedes usar directamente la función create_commit().
Hay tres tipos de operaciones admitidas por create_commit():
CommitOperationAdd sube un archivo al Hub. Si el archivo ya existe, se sobrescriben sus contenidos. Esta operación acepta dos argumentos:
path_in_repo: la ruta del repositorio a la que se subirá un archivo.path_or_fileobj: una ruta a un archivo en tu sistema de archivos o un objeto similar a un archivo. Este es el contenido del archivo que se subirá al Hub.
CommitOperationDelete elimina un archivo o una carpeta de un repositorio. Esta operación acepta
path_in_repocomo argumento.CommitOperationCopy copia un archivo dentro de un repositorio o entre repositorios. Esta operación acepta los siguientes argumentos:
src_path_in_repo: la ruta del archivo a copiar en el repositorio.path_in_repo: la ruta del repositorio donde se debe copiar el archivo.src_revision: opcional - la revisión del archivo a copiar si deseas copiar un archivo de una rama o revisión diferente.src_repo_id: opcional - el repositorio de origen del que se copiará (p. ej."username/source-model"). Por defecto, es el repositorio de destino.src_repo_type: opcional - el tipo del repositorio de origen ("model","dataset"o"space"). Obligatorio cuando se establecesrc_repo_id.
Por ejemplo, si quieres subir dos archivos y eliminar un archivo en un repositorio de Hub:
- Use la
CommitOperationadecuada para agregar o eliminar un archivo y para eliminar una carpeta:
>>> from huggingface_hub import HfApi, CommitOperationAdd, CommitOperationDelete
>>> api = HfApi()
>>> operations = [
... CommitOperationAdd(path_in_repo="LICENSE.md", path_or_fileobj="~/repo/LICENSE.md"),
... CommitOperationAdd(path_in_repo="weights.h5", path_or_fileobj="~/repo/weights-final.h5"),
... CommitOperationDelete(path_in_repo="old-weights.h5"),
... CommitOperationDelete(path_in_repo="logs/"),
... CommitOperationCopy(src_path_in_repo="image.png", path_in_repo="duplicate_image.png"),
... ]- Pasa tus operaciones a create_commit():
>>> api.create_commit(
... repo_id="lysandre/test-model",
... operations=operations,
... commit_message="Upload my model weights and license",
... )Además de upload_file() y upload_folder(), las siguientes funciones también utilizan create_commit() internamente:
- delete_file() elimina un único archivo de un repositorio en el Hub.
- delete_folder() elimina una carpeta completa de un repositorio en el Hub.
- metadata_update() actualiza los metadatos de un repositorio.
Para obtener información más detallada, consulte la referencia de HfApi.
Subir archivos LFS antes de confirmar
En algunos casos, es posible que desee cargar archivos enormes en S3 antes de realizar la llamada de commit. Por ejemplo, si está committing un dataset en varios shards que se generan en memoria, necesitaría cargar los shards uno por uno para evitar un problema de memoria insuficiente. Una solución es cargar cada shard como un commit separado en el repositorio. Si bien es perfectamente válido, esta solución tiene el inconveniente de potencialmente desordenar el historial de git al generar decenas de commits. Para superar este problema, puede cargar sus archivos uno por uno en S3 y luego crear un solo commit al final. Esto es posible usando preupload_lfs_files() en combinación con create_commit().
Este es un método para usuarios avanzados. En la gran mayoría de los casos, la mejor opción es usar directamente upload_file(), upload_folder() o create_commit() en lugar de gestionar la lógica de bajo nivel de la pre-carga de archivos. La principal precaución con preupload_lfs_files() es que, hasta que se realiza el commit, los archivos cargados no son accesibles en el repositorio del Hub. Si tienes alguna pregunta, no dudes en contactarnos en nuestro Discord o en un issue de GitHub.
Aquí hay un ejemplo sencillo que ilustra cómo pre-cargar archivos:
>>> from huggingface_hub import CommitOperationAdd, preupload_lfs_files, create_commit, create_repo
>>> repo_id = create_repo("test_preupload").repo_id
>>> operations = [] # List of all `CommitOperationAdd` objects that will be generated
>>> for i in range(5):
... content = ... # generate binary content
... addition = CommitOperationAdd(path_in_repo=f"shard_{i}_of_5.bin", path_or_fileobj=content)
... preupload_lfs_files(repo_id, additions=[addition])
... operations.append(addition)
>>> # Create commit
>>> create_commit(repo_id, operations=operations, commit_message="Commit all shards")Primero, creamos los objetos CommitOperationAdd uno a uno. En un ejemplo del mundo real, estos contendrían los fragmentos generados. Cada archivo se sube antes de generar el siguiente. Durante el paso preupload_lfs_files(), el objeto CommitOperationAdd se modifica. Deberías usarlo únicamente para pasarlo directamente a create_commit(). La principal actualización del objeto es que se elimina el contenido binario de él, lo que significa que será recolectado por el recolector de basura si no guardas otra referencia a él. Esto es esperado, ya que no queremos mantener en memoria el contenido que ya se ha subido. Finalmente, creamos el commit pasando todas las operaciones a create_commit(). Puedes pasar operaciones adicionales (add, delete o copy) que aún no hayan sido procesadas y se manejarán correctamente.