File size: 13,279 Bytes
fca804e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
# Hugging Face Hub Client library

## Download files from the Hub

The `hf_hub_download()` function is the main function to download files from the Hub. One
advantage of using it is that files are cached locally, so you won't have to
download the files multiple times. If there are changes in the repository, the
files will be automatically downloaded again.


### `hf_hub_download`

The function takes the following parameters, downloads the remote file,
stores it to disk (in a version-aware way) and returns its local file path.

Parameters:
- a `repo_id` (a user or organization name and a repo name, separated by `/`, like `julien-c/EsperBERTo-small`)
- a `filename` (like `pytorch_model.bin`)
- an optional Git revision id (can be a branch name, a tag, or a commit hash)
- a `cache_dir` which you can specify if you want to control where on disk the
  files are cached.

```python
from huggingface_hub import hf_hub_download
hf_hub_download("lysandre/arxiv-nlp", filename="config.json")
```

### `snapshot_download`

Using `hf_hub_download()` works well when you know which files you want to download;
for example a model file alongside a configuration file, both with static names.
There are cases in which you will prefer to download all the files of the remote
repository at a specified revision. That's what `snapshot_download()` does. It
downloads and stores a remote repository to disk (in a versioning-aware way) and
returns its local file path.

Parameters:
- a `repo_id` in the format `namespace/repository`
- a `revision` on which the repository will be downloaded
- a `cache_dir` which you can specify if you want to control where on disk the
  files are cached

### `hf_hub_url`

Internally, the library uses `hf_hub_url()` to return the URL to download the actual files:
`https://huggingface.co/julien-c/EsperBERTo-small/resolve/main/pytorch_model.bin`


Parameters:
- a `repo_id` (a user or organization name and a repo name separated by a `/`, like `julien-c/EsperBERTo-small`)
- a `filename` (like `pytorch_model.bin`)
- an optional `subfolder`, corresponding to a folder inside the model repo
- an optional `repo_type`, such as `dataset` or `space`
- an optional Git revision id (can be a branch name, a tag, or a commit hash)

If you check out this URL's headers with a `HEAD` http request (which you can do
from the command line with `curl -I`) for a few different files, you'll see
that:
- small files are returned directly
- large files (i.e. the ones stored through
  [git-lfs](https://git-lfs.github.com/)) are returned via a redirect to a
  Cloudfront URL. Cloudfront is a Content Delivery Network, or CDN, that ensures
  that downloads are as fast as possible from anywhere on the globe.

<br>

## Publish files to the Hub

If you've used Git before, this will be very easy since Git is used to manage
files in the Hub. You can find a step-by-step guide on how to upload your model
to the Hub: https://huggingface.co/docs/hub/adding-a-model.


### API utilities in `hf_api.py`

You don't need them for the standard publishing workflow (ie. using git command line), however, if you need a
programmatic way of creating a repo, deleting it (`⚠️ caution`), pushing a
single file to a repo or listing models from the Hub, you'll find helpers in
`hf_api.py`. Some example functionality available with the `HfApi` class:

* `whoami()`
* `create_repo()`
* `list_repo_files()`
* `list_repo_objects()`
* `delete_repo()`
* `update_repo_visibility()`
* `create_commit()`
* `upload_file()`
* `delete_file()`
* `delete_folder()`

Those API utilities are also exposed through the `huggingface-cli` CLI:

```bash
huggingface-cli login
huggingface-cli logout
huggingface-cli whoami
huggingface-cli repo create
```

With the `HfApi` class there are methods to query models, datasets, and metrics by specific tags (e.g. if you want to list models compatible with your library):
- **Models**:
  - `list_models()`
  - `model_info()`
  - `get_model_tags()`
- **Datasets**:
  - `list_datasets()`
  - `dataset_info()`
  - `get_dataset_tags()`
- **Spaces**:
  - `list_spaces()`
  - `space_info()`

These lightly wrap around the API Endpoints. Documentation for valid parameters and descriptions can be found [here](https://huggingface.co/docs/hub/endpoints).


### Advanced programmatic repository management

The `Repository` class helps manage both offline Git repositories and Hugging
Face Hub repositories. Using the `Repository` class requires `git` and `git-lfs`
to be installed.

Instantiate a `Repository` object by calling it with a path to a local Git
clone/repository:

```python
>>> from huggingface_hub import Repository
>>> repo = Repository("<path>/<to>/<folder>")
```

The `Repository` takes a `clone_from` string as parameter. This can stay as
`None` for offline management, but can also be set to any URL pointing to a Git
repo to clone that repository in the specified directory:

```python
>>> repo = Repository("huggingface-hub", clone_from="https://github.com/huggingface/huggingface_hub")
```

The `clone_from` method can also take any Hugging Face model ID as input, and
will clone that repository:

```python
>>> repo = Repository("w2v2", clone_from="facebook/wav2vec2-large-960h-lv60")
```

If the repository you're cloning is one of yours or one of your organisation's,
then having the ability to commit and push to that repository is important. In
order to do that, you should make sure to be logged-in using `huggingface-cli
login`, and to have the `token` parameter set to `True` (the default)
when  instantiating the `Repository` object:

```python
>>> repo = Repository("my-model", clone_from="<user>/<model_id>", token=True)
```

This works for models, datasets and spaces repositories; but you will need to
explicitely specify the type for the last two options:

```python
>>> repo = Repository("my-dataset", clone_from="<user>/<dataset_id>", token=True, repo_type="dataset")
```

You can also change between branches:

```python
>>> repo = Repository("huggingface-hub", clone_from="<user>/<dataset_id>", revision='branch1')
>>> repo.git_checkout("branch2")
```

The `clone_from` method can also take any Hugging Face model ID as input, and
will clone that repository:

```python
>>> repo = Repository("w2v2", clone_from="facebook/wav2vec2-large-960h-lv60")
```

Finally, you can choose to specify the Git username and email attributed to that
clone directly by using the `git_user` and `git_email` parameters. When
committing to that repository, Git will therefore be aware of who you are and
who will be the author of the commits:

```python
>>> repo = Repository(
...   "my-dataset",
...   clone_from="<user>/<dataset_id>",
...   token=True,
...   repo_type="dataset",
...   git_user="MyName",
...   git_email="[email protected]"
... )
```

The repository can be managed through this object, through wrappers of
traditional Git methods:

- `git_add(pattern: str, auto_lfs_track: bool)`. The `auto_lfs_track` flag
  triggers auto tracking of large files (>10MB) with `git-lfs`
- `git_commit(commit_message: str)`
- `git_pull(rebase: bool)`
- `git_push()`
- `git_checkout(branch)`

The `git_push` method has a parameter `blocking` which is `True` by default. When set to `False`, the push will
happen behind the scenes - which can be helpful if you would like your script to continue on while the push is
happening.

LFS-tracking methods:

- `lfs_track(pattern: Union[str, List[str]], filename: bool)`. Setting
  `filename` to `True` will use the `--filename` parameter, which will consider
  the pattern(s) as filenames, even if they contain special glob characters.
- `lfs_untrack()`.
- `auto_track_large_files()`: automatically tracks files that are larger than
  10MB. Make sure to call this after adding files to the index.

On top of these unitary methods lie some useful additional methods:

- `push_to_hub(commit_message)`: consecutively does `git_add`, `git_commit` and
  `git_push`.
- `commit(commit_message: str, track_large_files: bool)`: this is a context
  manager utility that handles committing to a repository. This automatically
  tracks large files (>10Mb) with `git-lfs`. The `track_large_files` argument can
  be set to `False` if you wish to ignore that behavior.

These two methods also have support for the `blocking` parameter.

Examples using the `commit` context manager:
```python
>>> with Repository("text-files", clone_from="<user>/text-files", token=True).commit("My first file :)"):
...     with open("file.txt", "w+") as f:
...         f.write(json.dumps({"hey": 8}))
```

```python
>>> import torch
>>> model = torch.nn.Transformer()
>>> with Repository("torch-model", clone_from="<user>/torch-model", token=True).commit("My cool model :)"):
...     torch.save(model.state_dict(), "model.pt")
  ```

### Non-blocking behavior

The pushing methods have access to a `blocking` boolean parameter to indicate whether the push should happen
asynchronously.

In order to see if the push has finished or its status code (to spot a failure), one should use the `command_queue`
property on the `Repository` object.

For example:

```python
from huggingface_hub import Repository

repo = Repository("<local_folder>", clone_from="<user>/<model_name>")

with repo.commit("Commit message", blocking=False):
    # Save data

last_command = repo.command_queue[-1]

# Status of the push command
last_command.status
# Will return the status code
#     -> -1 will indicate the push is still ongoing
#     -> 0 will indicate the push has completed successfully
#     -> non-zero code indicates the error code if there was an error

# if there was an error, the stderr may be inspected
last_command.stderr

# Whether the command finished or if it is still ongoing
last_command.is_done

# Whether the command errored-out.
last_command.failed
```

When using `blocking=False`, the commands will be tracked and your script will exit only when all pushes are done, even
if other errors happen in your script (a failed push counts as done).


### Need to upload very large (>5GB) files?

To upload large files (>5GB 🔥) from git command-line, you need to install the custom transfer agent
for git-lfs, bundled in this package.

To install, just run:

```bash
$ huggingface-cli lfs-enable-largefiles
```

This should be executed once for each model repo that contains a model file
>5GB. If you just try to push a file bigger than 5GB without running that
command, you will get an error with a message reminding you to run it.

Finally, there's a `huggingface-cli lfs-multipart-upload` command but that one
is internal (called by lfs directly) and is not meant to be called by the user.

<br>

## Using the Inference API wrapper

`huggingface_hub` comes with a wrapper client to make calls to the Inference
API! You can find some examples below, but we encourage you to visit the
Inference API
[documentation](https://api-inference.huggingface.co/docs/python/html/detailed_parameters.html)
to review the specific parameters for the different tasks.

When you instantiate the wrapper to the Inference API, you specify the model
repository id. The pipeline (`text-classification`,  `text-to-speech`, etc) is
automatically extracted from the
[repository](https://huggingface.co/docs/hub/main#how-is-a-models-type-of-inference-api-and-widget-determined),
but you can also override it as shown below.


### Examples

Here is a basic example of calling the Inference API for a `fill-mask` task
using the `bert-base-uncased` model. The `fill-mask` task only expects a string
(or list of strings) as input.

```python
from huggingface_hub.inference_api import InferenceApi
inference = InferenceApi("bert-base-uncased", token=API_TOKEN)
inference(inputs="The goal of life is [MASK].")
>> [{'sequence': 'the goal of life is life.', 'score': 0.10933292657136917, 'token': 2166, 'token_str': 'life'}]
```

This is an example of a task (`question-answering`) which requires a dictionary
as input thas has the `question` and `context` keys.

```python
inference = InferenceApi("deepset/roberta-base-squad2", token=API_TOKEN)
inputs = {"question":"What's my name?", "context":"My name is Clara and I live in Berkeley."}
inference(inputs)
>> {'score': 0.9326569437980652, 'start': 11, 'end': 16, 'answer': 'Clara'}
```

Some tasks might also require additional params in the request. Here is an
example using a `zero-shot-classification` model.

```python
inference = InferenceApi("typeform/distilbert-base-uncased-mnli", token=API_TOKEN)
inputs = "Hi, I recently bought a device from your company but it is not working as advertised and I would like to get reimbursed!"
params = {"candidate_labels":["refund", "legal", "faq"]}
inference(inputs, params)
>> {'sequence': 'Hi, I recently bought a device from your company but it is not working as advertised and I would like to get reimbursed!', 'labels': ['refund', 'faq', 'legal'], 'scores': [0.9378499388694763, 0.04914155602455139, 0.013008488342165947]}
```

Finally, there are some models that might support multiple tasks. For example,
`sentence-transformers` models can do `sentence-similarity` and
`feature-extraction`. You can override the configured task when initializing the
API.

```python
inference = InferenceApi("bert-base-uncased", task="feature-extraction", token=API_TOKEN)
```