|
| 1 | +--- |
| 2 | +description: Deploying your pipelines to Hugging Face Spaces. |
| 3 | +--- |
| 4 | + |
| 5 | +# Hugging Face Deployer |
| 6 | + |
| 7 | +[Hugging Face Spaces](https://huggingface.co/spaces) is a platform for hosting and sharing machine learning applications. The Hugging Face deployer is a [deployer](./) flavor included in the ZenML Hugging Face integration that deploys your pipelines to Hugging Face Spaces as Docker-based applications. |
| 8 | + |
| 9 | +{% hint style="warning" %} |
| 10 | +This component is only meant to be used within the context of a [remote ZenML installation](https://docs.zenml.io/getting-started/deploying-zenml). Usage with a local ZenML setup may lead to unexpected behavior! |
| 11 | +{% endhint %} |
| 12 | + |
| 13 | +## When to use it |
| 14 | + |
| 15 | +You should use the Hugging Face deployer if: |
| 16 | + |
| 17 | +* you're already using Hugging Face for model hosting or datasets. |
| 18 | +* you want to share your AI pipelines as publicly accessible or private Spaces. |
| 19 | +* you're looking for a simple, managed platform for deploying Docker-based applications. |
| 20 | +* you want to leverage Hugging Face's infrastructure for hosting your pipeline deployments. |
| 21 | +* you need an easy way to showcase ML workflows to the community. |
| 22 | + |
| 23 | +## How to deploy it |
| 24 | + |
| 25 | +{% hint style="info" %} |
| 26 | +The Hugging Face deployer requires a remote ZenML installation. You must ensure that you are connected to the remote ZenML server before using this stack component. |
| 27 | +{% endhint %} |
| 28 | + |
| 29 | +In order to use a Hugging Face deployer, you need to first deploy [ZenML to the cloud](https://docs.zenml.io/getting-started/deploying-zenml/). |
| 30 | + |
| 31 | +The only other requirement is having a Hugging Face account and generating an access token with write permissions. |
| 32 | + |
| 33 | +## How to use it |
| 34 | + |
| 35 | +To use the Hugging Face deployer, you need: |
| 36 | + |
| 37 | +* The ZenML `huggingface` integration installed. If you haven't done so, run |
| 38 | + |
| 39 | + ```shell |
| 40 | + zenml integration install huggingface |
| 41 | + ``` |
| 42 | +* [Docker](https://www.docker.com) installed and running. |
| 43 | +* A [remote artifact store](https://docs.zenml.io/stacks/artifact-stores/) as part of your stack. |
| 44 | +* A [remote container registry](https://docs.zenml.io/stacks/container-registries/) as part of your stack. |
| 45 | +* A [Hugging Face access token with write permissions](https://huggingface.co/settings/tokens) |
| 46 | + |
| 47 | +### Hugging Face credentials |
| 48 | + |
| 49 | +You need a Hugging Face access token with write permissions to deploy pipelines. You can create one at [https://huggingface.co/settings/tokens](https://huggingface.co/settings/tokens). |
| 50 | + |
| 51 | +You have two options to provide credentials to the Hugging Face deployer: |
| 52 | + |
| 53 | +* Pass the token directly when registering the deployer using the `--token` parameter |
| 54 | +* (recommended) Store the token in a ZenML secret and reference it using [secret reference syntax](https://docs.zenml.io/how-to/project-setup-and-management/interact-with-secrets) |
| 55 | + |
| 56 | +### Registering the deployer |
| 57 | + |
| 58 | +The deployer can be registered as follows: |
| 59 | + |
| 60 | +```shell |
| 61 | +# Option 1: Direct token (not recommended for production) |
| 62 | +zenml deployer register <DEPLOYER_NAME> \ |
| 63 | + --flavor=huggingface \ |
| 64 | + --token=<YOUR_HF_TOKEN> |
| 65 | + |
| 66 | +# Option 2: Using a secret (recommended) |
| 67 | +zenml secret create hf_token --token=<YOUR_HF_TOKEN> |
| 68 | +zenml deployer register <DEPLOYER_NAME> \ |
| 69 | + --flavor=huggingface \ |
| 70 | + --token='{{hf_token.token}}' |
| 71 | +``` |
| 72 | + |
| 73 | +### Configuring the stack |
| 74 | + |
| 75 | +With the deployer registered, it can be used in the active stack: |
| 76 | + |
| 77 | +```shell |
| 78 | +# Register and activate a stack with the new deployer |
| 79 | +zenml stack register <STACK_NAME> -D <DEPLOYER_NAME> ... --set |
| 80 | +``` |
| 81 | + |
| 82 | +{% hint style="info" %} |
| 83 | +ZenML will build a Docker image called `<CONTAINER_REGISTRY_URI>/zenml:<PIPELINE_NAME>` which will be referenced in a Dockerfile deployed to your Hugging Face Space. Check out [this page](https://docs.zenml.io/how-to/customize-docker-builds/) if you want to learn more about how ZenML builds these images and how you can customize them. |
| 84 | +{% endhint %} |
| 85 | + |
| 86 | +You can now [deploy any ZenML pipeline](https://docs.zenml.io/concepts/deployment) using the Hugging Face deployer: |
| 87 | + |
| 88 | +```shell |
| 89 | +zenml pipeline deploy --name my_deployment my_module.my_pipeline |
| 90 | +``` |
| 91 | + |
| 92 | +### Additional configuration |
| 93 | + |
| 94 | +For additional configuration of the Hugging Face deployer, you can pass the following `HuggingFaceDeployerSettings` attributes defined in the `zenml.integrations.huggingface.flavors.huggingface_deployer_flavor` module when configuring the deployer or defining or deploying your pipeline: |
| 95 | + |
| 96 | +* Basic settings common to all Deployers: |
| 97 | + |
| 98 | + * `auth_key`: A user-defined authentication key to use to authenticate with deployment API calls. |
| 99 | + * `generate_auth_key`: Whether to generate and use a random authentication key instead of the user-defined one. |
| 100 | + * `lcm_timeout`: The maximum time in seconds to wait for the deployment lifecycle management to complete. |
| 101 | + |
| 102 | +* Hugging Face Spaces-specific settings: |
| 103 | + |
| 104 | + * `space_hardware` (default: `None`): Hardware tier for the Space (e.g., `'cpu-basic'`, `'cpu-upgrade'`, `'t4-small'`, `'t4-medium'`, `'a10g-small'`, `'a10g-large'`). If not specified, uses free CPU tier. See [Hugging Face Spaces GPU documentation](https://huggingface.co/docs/hub/spaces-gpus) for available options and pricing. |
| 105 | + * `space_storage` (default: `None`): Persistent storage tier for the Space (e.g., `'small'`, `'medium'`, `'large'`). If not specified, no persistent storage is allocated. |
| 106 | + * `private` (default: `True`): Whether to create the Space as private. Set to `False` to make the Space publicly visible to everyone. |
| 107 | + * `app_port` (default: `8000`): Port number where your deployment server listens. Defaults to 8000 (ZenML server default). Hugging Face Spaces will route traffic to this port. |
| 108 | + |
| 109 | +Check out [this docs page](https://docs.zenml.io/concepts/steps_and_pipelines/configuration) for more information on how to specify settings. |
| 110 | + |
| 111 | +For example, if you wanted to deploy on GPU hardware with persistent storage, you would configure settings as follows: |
| 112 | + |
| 113 | +```python |
| 114 | +from zenml.integrations.huggingface.deployers import HuggingFaceDeployerSettings |
| 115 | + |
| 116 | +huggingface_settings = HuggingFaceDeployerSettings( |
| 117 | + space_hardware="t4-small", |
| 118 | + space_storage="small", |
| 119 | + # private=True is the default for security |
| 120 | +) |
| 121 | + |
| 122 | +@pipeline( |
| 123 | + settings={ |
| 124 | + "deployer": huggingface_settings |
| 125 | + } |
| 126 | +) |
| 127 | +def my_pipeline(...): |
| 128 | + ... |
| 129 | +``` |
| 130 | + |
| 131 | +### Managing deployments |
| 132 | + |
| 133 | +Once deployed, you can manage your deployments using the ZenML CLI: |
| 134 | + |
| 135 | +```shell |
| 136 | +# List all deployments |
| 137 | +zenml deployment list |
| 138 | + |
| 139 | +# Get deployment status |
| 140 | +zenml deployment describe <DEPLOYMENT_NAME> |
| 141 | + |
| 142 | +# Get deployment logs |
| 143 | +zenml deployment logs <DEPLOYMENT_NAME> |
| 144 | + |
| 145 | +# Delete a deployment |
| 146 | +zenml deployment delete <DEPLOYMENT_NAME> |
| 147 | +``` |
| 148 | + |
| 149 | +The deployed pipeline will be available as a Hugging Face Space at: |
| 150 | +``` |
| 151 | +https://huggingface.co/spaces/<YOUR_USERNAME>/<SPACE_PREFIX>-<DEPLOYMENT_NAME> |
| 152 | +``` |
| 153 | + |
| 154 | +By default, the space prefix is `zenml` but this can be configured using the `space_prefix` parameter when registering the deployer. |
| 155 | + |
| 156 | +## Important Requirements |
| 157 | + |
| 158 | +### Secure Secrets and Environment Variables |
| 159 | + |
| 160 | +{% hint style="success" %} |
| 161 | +The Hugging Face deployer handles secrets and environment variables **securely** using Hugging Face's Space Secrets and Variables API. Credentials are **never** written to the Dockerfile. |
| 162 | +{% endhint %} |
| 163 | + |
| 164 | +**How it works:** |
| 165 | +- Environment variables are set using `HfApi.add_space_variable()` - stored securely by Hugging Face |
| 166 | +- Secrets are set using `HfApi.add_space_secret()` - encrypted and never exposed in the Space repository |
| 167 | +- **Nothing is baked into the Dockerfile** - no risk of leaked credentials even in public Spaces |
| 168 | + |
| 169 | +**What this means:** |
| 170 | +- ✅ Safe to use with both private and public Spaces |
| 171 | +- ✅ Secrets remain encrypted and hidden from view |
| 172 | +- ✅ Environment variables are managed through HF's secure API |
| 173 | +- ✅ No credentials exposed in Dockerfile or repository files |
| 174 | + |
| 175 | +This secure approach ensures that if you choose to make your Space public (`private=False`), credentials remain protected and are never visible to anyone viewing your Space's repository. |
| 176 | + |
| 177 | +### Container Registry Requirement |
| 178 | + |
| 179 | +{% hint style="warning" %} |
| 180 | +The Hugging Face deployer **requires** a container registry to be part of your ZenML stack. The Docker image must be pre-built and pushed to a **publicly accessible** container registry. |
| 181 | +{% endhint %} |
| 182 | + |
| 183 | +**Why public access is required:** |
| 184 | +Hugging Face Spaces cannot authenticate with private Docker registries when building Docker Spaces. The platform pulls your Docker image during the build process, which means it needs public access. |
| 185 | + |
| 186 | +**Recommended registries:** |
| 187 | +- [Docker Hub](https://hub.docker.com/) public repositories |
| 188 | +- [GitHub Container Registry (GHCR)](https://ghcr.io) with public images |
| 189 | +- Any other public container registry |
| 190 | + |
| 191 | +**Example setup with GitHub Container Registry:** |
| 192 | +```shell |
| 193 | +# Register a public container registry |
| 194 | +zenml container-registry register ghcr_public \ |
| 195 | + --flavor=default \ |
| 196 | + --uri=ghcr.io/<your-github-username> |
| 197 | + |
| 198 | +# Add it to your stack |
| 199 | +zenml stack update <STACK_NAME> --container-registry=ghcr_public |
| 200 | +``` |
| 201 | + |
| 202 | +### Configuring iframe Embedding (X-Frame-Options) |
| 203 | + |
| 204 | +By default, ZenML's deployment server sends an `X-Frame-Options` header that prevents the deployment UI from being embedded in iframes. This causes issues with Hugging Face Spaces, which displays deployments in an iframe. |
| 205 | + |
| 206 | +**To fix this**, you must configure your pipeline's `DeploymentSettings` to disable the `X-Frame-Options` header: |
| 207 | + |
| 208 | +```python |
| 209 | +from zenml import pipeline |
| 210 | +from zenml.config import DeploymentSettings, SecureHeadersConfig |
| 211 | + |
| 212 | +# Configure deployment settings |
| 213 | +deployment_settings = DeploymentSettings( |
| 214 | + app_title="My ZenML Pipeline", |
| 215 | + app_description="ML pipeline deployed to Hugging Face Spaces", |
| 216 | + app_version="1.0.0", |
| 217 | + secure_headers=SecureHeadersConfig( |
| 218 | + xfo=False, # Disable X-Frame-Options to allow iframe embedding |
| 219 | + server=True, |
| 220 | + hsts=False, |
| 221 | + content=True, |
| 222 | + referrer=True, |
| 223 | + cache=True, |
| 224 | + permissions=True, |
| 225 | + ), |
| 226 | + cors={ |
| 227 | + "allow_origins": ["*"], |
| 228 | + "allow_methods": ["GET", "POST", "OPTIONS"], |
| 229 | + "allow_headers": ["*"], |
| 230 | + "allow_credentials": False, |
| 231 | + }, |
| 232 | +) |
| 233 | + |
| 234 | +@pipeline( |
| 235 | + name="my_hf_pipeline", |
| 236 | + settings={"deployment": deployment_settings} |
| 237 | +) |
| 238 | +def my_pipeline(): |
| 239 | + # Your pipeline steps here |
| 240 | + pass |
| 241 | +``` |
| 242 | + |
| 243 | +Without this configuration, the Hugging Face Spaces UI will show a blank page or errors when trying to display your deployment. |
| 244 | + |
| 245 | +## Additional Resources |
| 246 | + |
| 247 | +* [Hugging Face Spaces Documentation](https://huggingface.co/docs/hub/spaces) |
| 248 | +* [Docker Spaces Guide](https://huggingface.co/docs/hub/spaces-sdks-docker) |
| 249 | +* [Hugging Face Hardware Options](https://huggingface.co/docs/hub/spaces-gpus) |
| 250 | +* [ZenML Deployment Concepts](https://docs.zenml.io/concepts/deployment) |
0 commit comments