Hub Python Library documentation
Herhangi bir ML çerçevesini Hub ile entegre edin
Herhangi bir ML çerçevesini Hub ile entegre edin
Hugging Face Hub, modelleri toplulukla barındırma ve paylaşma işlemlerini kolaylaştırır. Açık Kaynak ekosistemindeki onlarca kütüphaneyi destekler. İşbirliğine dayalı Makine Öğrenmesini ileriye taşımak için bu desteği sürekli olarak genişletmek üzerinde çalışıyoruz. huggingface_hub kütüphanesi bu süreçte kilit bir rol oynar ve herhangi bir Python betiğinin dosyaları kolayca gönderip yüklemesini sağlar.
Bir kütüphaneyi Hub ile entegre etmenin dört ana yolu vardır:
- Hub'a Yükle: bir modeli Hub'a yüklemek için bir yöntem uygulayın. Bu, model ağırlıklarının yanı sıra model kartını ve modeli çalıştırmak için gerekli olan diğer ilgili bilgiler veya verileri (örneğin, eğitim günlükleri) içerir. Bu yöntem genellikle
push_to_hub()olarak adlandırılır. - Hub'dan indir: Hub'dan bir model yüklemek için bir yöntem uygulayın. Yöntem, model yapılandırmasını/ağırlıklarını indirmeli ve modeli yüklemelidir. Bu yöntem genellikle
from_pretrainedveyaload_from_hub()olarak adlandırılır. - Widget'ler: Hub'daki modellerinizin açılış sayfasında bir widget görüntüler. Kullanıcıların bir modeli tarayıcıdan hızlıca denemesini sağlar.
Bu kılavuzda ilk iki konuya odaklanacağız. Bir kütüphaneyi entegre etmek için kullanabileceğiniz iki ana yaklaşımı, avantajları ve dezavantajlarıyla birlikte sunacağız. İki seçenek arasında seçim yapmanıza yardımcı olmak için her şey kılavuzun sonunda özetlenmiştir. Lütfen bunların yalnızca gereksinimlerinize göre serbestçe uyarlayabileceğiniz yönergeler olduğunu aklınızda bulundurun.
Inference ve Widgets ile ilgileniyorsanız, bu kılavuza göz atabilirsiniz. Her iki durumda da, bir kütüphaneyi Hub ile entegre ediyorsanız ve belgelerimizde listelenmek istiyorsanız bize ulaşabilirsiniz.
Esnek bir yaklaşım: yardımcılar
Hub'a bir kütüphaneyi entegre etmenin ilk yaklaşımı, push_to_hub ve from_pretrained yöntemlerini kendiniz uygulamaktır. Bu, yüklemeniz/indirmeniz gereken dosyalar ve çerçevenize özgü girdileri nasıl işleyeceğiniz konusunda size tam esneklik sağlar. Bunu nasıl yapacağınızı öğrenmek için dosya yükleme ve dosya indirme kılavuzlarına başvurabilirsiniz. Örneğin, FastAI entegrasyonu bu şekilde uygulanmıştır (bkz. push_to_hub_fastai() ve from_pretrained_fastai()).
Uygulama, kütüphaneler arasında farklılık gösterebilir, ancak iş akışı genellikle benzerdir.
from_pretrained
from_pretrained yöntemi genellikle şu şekilde görünür:
def from_pretrained(model_id: str) -> MyModelClass:
# Download model from Hub
cached_model = hf_hub_download(
repo_id=model_id,
filename="model.pkl",
library_name="fastai",
library_version=get_fastai_version(),
)
# Load model
return load_model(cached_model)push_to_hub
push_to_hub yöntemi, depo oluşturma, model kartı oluşturma ve ağırlıkları kaydetme işlemlerini yönetmek için genellikle biraz daha fazla karmaşıklık gerektirir.
Yaygın bir yaklaşım, bu dosyaların tümünü geçici bir klasöre kaydetmek, yüklemek ve ardından silmektir.
def push_to_hub(model: MyModelClass, repo_name: str) -> None:
api = HfApi()
# Create repo if not existing yet and get the associated repo_id
repo_id = api.create_repo(repo_name, exist_ok=True)
# Save all files in a temporary directory and push them in a single commit
with TemporaryDirectory() as tmpdir:
tmpdir = Path(tmpdir)
# Save weights
save_model(model, tmpdir / "model.safetensors")
# Generate model card
card = generate_model_card(model)
(tmpdir / "README.md").write_text(card)
# Save logs
# Save figures
# Save evaluation metrics
# ...
# Push to hub
return api.upload_folder(repo_id=repo_id, folder_path=tmpdir)Bu elbette yalnızca bir örnektir. Daha karmaşık işlemlerle (uzaktaki dosyaları silme, ağırlıkları anlık olarak yükleme, ağırlıkları yerel olarak kalıcı hale getirme vb.) ilgileniyorsanız lütfen dosya yükleme kılavuzuna başvurun.
Kısıtlamalar
Esnek olmasına rağmen bu yaklaşımın bazı dezavantajları vardır, özellikle bakım açısından. Hugging Face kullanıcıları, huggingface_hub ile çalışırken ek özelliklere alışkındır. Örneğin, Hub'dan dosya yüklerken şu parametreleri sunmak yaygındır:
token: özel bir depodan indirmek içinrevision: belirli bir daldan indirmek içincache_dir: dosyaları belirli bir dizinde önbelleğe almak içinforce_download/local_files_only: önbelleğin yeniden kullanılacak olup olmadığıproxies: HTTP oturumunu yapılandır
Modelleri ittirirken, benzer parametreler desteklenir:
commit_message: özel commit mesajıprivate: eksikse özel bir depo oluşturcreate_pr:maindalına push yapmak yerine bir PR oluşturunbranch:maindalı yerine bir dala gönderallow_patterns/ignore_patterns: yüklemek istediğiniz dosyaları filtreleyintoken- …
Tüm bu parametreler, yukarıda gördüğümüz uygulamalara eklenebilir ve huggingface_hub yöntemlerine aktarılabilir.
Ancak bir parametre değişirse veya yeni bir özellik eklenirse, paketinizi güncellemeniz gerekir. Bu parametreleri desteklemek,
sizin tarafınızda daha fazla dokümantasyonun sürdürülmesi anlamına gelir. Bu kısıtlamaları nasıl azaltabileceğinizi görmek için
sonraki bölümümüze sınıf kalıtımı kısmına geçelim.
Daha karmaşık bir yaklaşım: sınıf kalıtımı
Yukarıda gördüğümüz gibi, kütüphanenizi Hub ile entegre etmek için dahil etmeniz gereken iki ana yöntem vardır: dosya yükleme (push_to_hub) ve dosya indirme (from_pretrained). Bu yöntemleri kendiniz uygulayabilirsiniz ancak bu durum bazı dikkat edilmesi gereken noktalar içerir. Bu sorunu çözmek için huggingface_hub, sınıf kalıtımı kullanan bir araç sağlar. Nasıl çalıştığını görelim!
In a lot of cases, a library already implements its model using a Python class. The class contains the properties of
the model and methods to load, run, train, and evaluate it. Our approach is to extend this class to include upload and
download features using mixins. A Mixin is a class that is meant to extend an
existing class with a set of specific features using multiple inheritance. huggingface_hub provides its own mixin,
the ModelHubMixin. The key here is to understand its behavior and how to customize it.
ModelHubMixin sınıfı 3 public yöntem (push_to_hub, save_pretrained ve from_pretrained) uygular. Bunlar, kullanıcılarınızın kütüphanenizle modelleri yüklemek/kaydetmek için çağıracağı yöntemlerdir. ModelHubMixin ayrıca 2 private yöntem (_save_pretrained ve _from_pretrained) tanımlar. Bunlar sizin uygulamanız gereken yöntemlerdir. Dolayısıyla kütüphanenizi entegre etmek için:
- Model sınıfınızı ModelHubMixin sınıfından türetin.
- Özel yöntemleri uygulayın:
- _save_pretrained(): bir dizin yolunu girdi olarak alıp modeli bu dizine kaydeden yöntem. Modelinizi dışa aktarmak için tüm mantığı bu yönteme yazmalısınız: model kartı, model ağırlıkları, yapılandırma dosyaları, eğitim günlükleri ve şekiller. Bu modelle ilgili tüm ilgili bilgiler bu yöntem tarafından ele alınmalıdır. Modelinizi açıklamak için Model Kartları özellikle önemlidir. Daha fazla ayrıntı için uygulama kılavuzumuza göz atın.
- _from_pretrained():
model_idgirdi alıp örneklenmiş bir model döndüren sınıf yöntemi. Yöntem, ilgili dosyaları indirmeli ve yüklemelidir.
- Bitti!
ModelHubMixin kullanmanın avantajı, dosyaların seri hale getirilme/yükleme işlemlerini hallettiğinizde her şeyin hazır olmasıdır. Repo oluşturma, commit, PR veya revizyon gibi konularla uğraşmanıza gerek yoktur. ModelHubMixin, ayrıca genel metodların dokümante edilmesini ve tip etiketli olmasını sağlar; modelinizin Hub’daki indirme sayısını görüntüleyebilirsiniz. Tüm bunlar ModelHubMixin tarafından yönetilir ve kullanıcılarınızın kullanımına sunulur.
Somut bir örnek: PyTorch
Yukarıda gördüklerimizin iyi bir örneği, PyTorch çerçevesi için entegrasyonumuz olan PyTorchModelHubMixin'dir. Bu, kullanıma hazır bir entegrasyondur.
Nasıl kullanılır?
Herhangi bir kullanıcının Hub'dan bir PyTorch modelini yüklemesinin/kaydetmesinin yöntemi aşağıdaki gibidir:
>>> import torch
>>> import torch.nn as nn
>>> from huggingface_hub import PyTorchModelHubMixin
# Define your Pytorch model exactly the same way you are used to
>>> class MyModel(
... nn.Module,
... PyTorchModelHubMixin, # multiple inheritance
... library_name="keras-nlp",
... tags=["keras"],
... repo_url="https://github.com/keras-team/keras-nlp",
... docs_url="https://keras.io/keras_nlp/",
... # ^ optional metadata to generate model card
... ):
... def __init__(self, hidden_size: int = 512, vocab_size: int = 30000, output_size: int = 4):
... super().__init__()
... self.param = nn.Parameter(torch.rand(hidden_size, vocab_size))
... self.linear = nn.Linear(output_size, vocab_size)
... def forward(self, x):
... return self.linear(x + self.param)
# 1. Create model
>>> model = MyModel(hidden_size=128)
# Config is automatically created based on input + default values
>>> model.param.shape[0]
128
# 2. (optional) Save model to local directory
>>> model.save_pretrained("path/to/my-awesome-model")
# 3. Push model weights to the Hub
>>> model.push_to_hub("my-awesome-model")
# 4. Initialize model from the Hub => config has been preserved
>>> model = MyModel.from_pretrained("username/my-awesome-model")
>>> model.param.shape[0]
128
# Model card has been correctly populated
>>> from huggingface_hub import ModelCard
>>> card = ModelCard.load("username/my-awesome-model")
>>> card.data.tags
["keras", "pytorch_model_hub_mixin", "model_hub_mixin"]
>>> card.data.library_name
"keras-nlp"Uygulama
Uygulama aslında oldukça basittir ve tam uygulama burada bulunabilir.
- Önce sınıfınızı
ModelHubMixinsınıfından türetin:
from huggingface_hub import ModelHubMixin
class PyTorchModelHubMixin(ModelHubMixin):
(...)_save_pretrainedmetodunu uygulayın:
from huggingface_hub import ModelHubMixin
class PyTorchModelHubMixin(ModelHubMixin):
(...)
def _save_pretrained(self, save_directory: Path) -> None:
"""Save weights from a Pytorch model to a local directory."""
save_model_as_safetensor(self.module, str(save_directory / SAFETENSORS_SINGLE_FILE))
_from_pretrainedmetodunu uygulayın:
class PyTorchModelHubMixin(ModelHubMixin):
(...)
@classmethod # Must be a classmethod!
def _from_pretrained(
cls,
*,
model_id: str,
revision: str,
cache_dir: str,
force_download: bool,
local_files_only: bool,
token: Union[str, bool, None],
map_location: str = "cpu", # additional argument
strict: bool = False, # additional argument
**model_kwargs,
):
"""Load Pytorch pretrained weights and return the loaded model."""
model = cls(**model_kwargs)
if os.path.isdir(model_id):
print("Loading weights from local directory")
model_file = os.path.join(model_id, SAFETENSORS_SINGLE_FILE)
return cls._load_as_safetensor(model, model_file, map_location, strict)
model_file = hf_hub_download(
repo_id=model_id,
filename=SAFETENSORS_SINGLE_FILE,
revision=revision,
cache_dir=cache_dir,
force_download=force_download,
token=token,
local_files_only=local_files_only,
)
return cls._load_as_safetensor(model, model_file, map_location, strict)Ve tamam! Kütüphaneniz artık kullanıcıların Hub'a dosya yüklemesini ve Hub'dan dosya indirmesini mümkün kılıyor.
Gelişmiş kullanım
Yukarıdaki bölümde ModelHubMixin'in nasıl çalıştığını kısaca ele aldık. Bu bölümde, kütüphanenizin Hugging Face Hub ile entegrasyonunu geliştirmek için bu sınıfın daha gelişmiş özelliklerinden bazılarını inceleyeceğiz.
Model kartı
ModelHubMixin model kartını sizin için oluşturur. Model kartları, modellerle birlikte gelen ve onlar hakkında önemli bilgiler sağlayan dosyalardır. Arka planda, model kartları ek meta verilere sahip basit Markdown dosyalarıdır. Model kartları keşfedilebilirlik, yeniden üretilebilirlik ve paylaşım için hayati öneme sahiptir! Daha fazla ayrıntı için Model Kartları kılavuzuna göz atın.
Model kartlarını yarı otomatik olarak oluşturmak, kütüphanenizle gönderilen tüm modellerin ortak meta verileri paylaşmasını sağlamanın iyi bir yoludur: library_name, tags, license, pipeline_tag vb. Bu, kütüphaneniz tarafından desteklenen tüm modellerin Hub'da kolayca aranabilir olmasını sağlar ve Hub'a gelen kullanıcılara bazı kaynak bağlantıları sunar. ModelHubMixin'den devralırken meta verileri doğrudan tanımlayabilirsiniz:
class UniDepthV1(
nn.Module,
PyTorchModelHubMixin,
library_name="unidepth",
repo_url="https://github.com/lpiccinelli-eth/UniDepth",
docs_url=...,
pipeline_tag="depth-estimation",
license="cc-by-nc-4.0",
tags=["monocular-metric-depth-estimation", "arxiv:1234.56789"]
):
...Varsayılan olarak, sağladığınız bilgilerle genel bir model kartı oluşturulur (örnek: pyp1/VoiceCraft_giga830M). Ancak kendi model kartı şablonunuzu da tanımlayabilirsiniz!
Bu örnekte, VoiceCraft sınıfıyla itilen tüm modeller otomatik olarak bir alıntı bölümü ve lisans ayrıntıları içerecektir. Model kartı şablonunun nasıl tanımlanacağına dair daha fazla ayrıntı için lütfen Model Cards kılavuzunu kontrol edin.
MODEL_CARD_TEMPLATE = """
---
# For reference on model card metadata, see the spec: https://github.com/huggingface/hub-docs/blob/main/modelcard.md?plain=1
# Doc / guide: https://huggingface.co/docs/hub/model-cards
{{ card_data }}
---
This is a VoiceCraft model. For more details, please check out the official Github repo: https://github.com/jasonppy/VoiceCraft. This model is shared under a Attribution-NonCommercial-ShareAlike 4.0 International license.
## Citation
@article{peng2024voicecraft,
author = {Peng, Puyuan and Huang, Po-Yao and Li, Daniel and Mohamed, Abdelrahman and Harwath, David},
title = {VoiceCraft: Zero-Shot Speech Editing and Text-to-Speech in the Wild},
journal = {arXiv},
year = {2024},
}
"""
class VoiceCraft(
nn.Module,
PyTorchModelHubMixin,
library_name="voicecraft",
model_card_template=MODEL_CARD_TEMPLATE,
...
):
...Son olarak, model kartı oluşturma sürecini dinamik değerlerle genişletmek istiyorsanız generate_model_card() metodunu geçersiz kılabilirsiniz:
from huggingface_hub import ModelCard, PyTorchModelHubMixin
class UniDepthV1(nn.Module, PyTorchModelHubMixin, ...):
(...)
def generate_model_card(self, *args, **kwargs) -> ModelCard:
card = super().generate_model_card(*args, **kwargs)
card.data.metrics = ... # add metrics to the metadata
card.text += ... # append section to the modelcard
return cardYapılandırma
ModelHubMixin model yapılandırmasını sizin için yönetir. Modeli örneklediğinizde girdi değerlerini otomatik olarak kontrol eder ve bunları config.json dosyasında seri hale getirir. Bu, iki avantaj sağlar:
- Kullanıcılar, modeli sizinle aynı parametrelerle yeniden yükleyebilecek.
config.jsondosyasına sahip olmak, Hub'da analitiği (yani “downloads” sayacını) otomatik olarak etkinleştirir.
Peki pratikte nasıl çalışır? Kullanıcı perspektifinden süreci olabildiğince akıcı hale getiren birkaç kural vardır:
__init__yönteminiz birconfiggirdisi bekliyorsa, bu girdi depoda otomatik olarakconfig.jsonolarak kaydedilir.configgiriş parametresi bir dataclass tipiyle (ör.config: Optional[MyConfigClass] = None) işaretlenmişse,configdeğeri sizin için doğru şekilde serileştirme kaldırılır.- başlatma sırasında geçirilen tüm değerler ayrıca yapılandırma dosyasında da saklanır. Bu, bundan yararlanmak için mutlaka bir
configgirdisi beklemeniz gerektiği anlamına gelmez.
Örnek:
class MyModel(ModelHubMixin):
def __init__(value: str, size: int = 3):
self.value = value
self.size = size
(...) # implement _save_pretrained / _from_pretrained
model = MyModel(value="my_value")
model.save_pretrained(...)
# config.json contains passed and default values
{"value": "my_value", "size": 3}Peki, bir değer JSON olarak serialize edilemezse? Varsayılan olarak, config dosyası kaydedilirken bu değer yok sayılır. Ancak bazı durumlarda, kütüphaneniz zaten serialize edilemeyen özel bir nesneyi girdi olarak bekliyor olabilir ve iç mantığınızı güncellemek için tipini değiştirmek istemeyebilirsiniz. Endişelenmeyin! ModelHubMixin sınıfından türetirken herhangi bir tip için özel encoder/decoder geçebilirsiniz. Bu biraz daha fazla iş gerektirir, ancak kütüphanenizi Hub ile entegre ederken iç mantığınızın dokunulmamış kalmasını sağlar.
Bir sınıfın girdi olarak argparse.Namespace yapılandırması beklediği somut bir örnek:
class VoiceCraft(nn.Module):
def __init__(self, args):
self.pattern = self.args.pattern
self.hidden_size = self.args.hidden_size
...Bir çözüm, __init__ imzasını def __init__(self, pattern: str, hidden_size: int) olarak güncellemek ve sınıfınızı örnekleyen tüm kod parçacıklarını güncellemek olabilir. Bu, sorunu gidermenin tamamen geçerli bir yoludur ancak kütüphanenizi kullanan aşağı akış uygulamalarını bozabilir.
Bir başka çözüm, argparse.Namespace'i bir sözlüğe dönüştürmek için basit bir kodlayıcı/çözücü sağlamaktır.
from argparse import Namespace
class VoiceCraft(
nn.Module,
PyTorchModelHubMixin, # inherit from mixin
coders={
Namespace : (
lambda x: vars(x), # Encoder: how to convert a `Namespace` to a valid jsonable value?
lambda data: Namespace(**data), # Decoder: how to reconstruct a `Namespace` from a dictionary?
)
}
):
def __init__(self, args: Namespace): # annotate `args`
self.pattern = self.args.pattern
self.hidden_size = self.args.hidden_size
...Yukarıdaki parçada, sınıfın hem iç mantığı hem de __init__ imzası değişmedi. Bu, kütüphaneniz için mevcut tüm kod parçacıklarının çalışmaya devam edeceği anlamına gelir. Bunu başarmak için şunları yapmak zorunda kaldık:
- Karışım sınıftan (
PytorchModelHubMixinbu durumda) devralın. - Miras alımda bir
codersparametresi geçirin. Bu, anahtarları işlenmesini istediğiniz özel türler olan bir sözlüktür. Değerler bir demettir(encoder, decoder).- Encoder, girdi olarak belirtilen türde bir nesne bekler ve jsonable bir değer döndürür. Bu, bir modelin
save_pretrainedile kaydedilmesi sırasında kullanılacaktır. - Decoder, girdi olarak ham veriyi (genellikle bir sözlük) bekler ve başlangıç nesnesini yeniden oluşturur. Bu, modelin
from_pretrainedile yüklenmesi sırasında kullanılacaktır.
- Encoder, girdi olarak belirtilen türde bir nesne bekler ve jsonable bir değer döndürür. Bu, bir modelin
__init__imzasına bir tür anotasyonu ekleyin. Bu, sınıfın hangi türü beklediğini ve dolayısıyla hangi çözücünün kullanılacağını mixin'e bildirmek için önemlidir.
Basitlik adına, yukarıdaki örnekteki kodlayıcı/çözücü işlevleri sağlam değildir. Somut bir uygulama için muhtemelen köşe durumlarını düzgün bir şekilde ele almanız gerekecektir.
Hızlı karşılaştırma
Gördüğümüz iki yaklaşımı avantaj ve dezavantajlarıyla kısaca özetleyelim. Aşağıdaki tablo yalnızca bilgilendirme amaçlıdır. Çerçevenizin, ele almanız gereken bazı özgünlükleri olabilir. Bu kılavuz yalnızca entegrasyonu nasıl yöneteceğinize dair yönergeler ve fikirler sunmak için burada. Herhangi bir sorunuz olursa bizimle iletişime geçmekten çekinmeyin!
| Entegrasyon | Yardımcıların kullanımı | ModelHubMixin kullanımı |
|---|---|---|
| Kullanıcı deneyimi | model = load_from_hub(...)push_to_hub(model, ...) | model = MyModel.from_pretrained(...)model.push_to_hub(...) |
| Esneklik | Çok esnek. Uygulamayı tamamen siz kontrol edersiniz. | Daha az esnek. Çerçevenizin bir model sınıfı olmalıdır. |
| Bakım | Yapılandırma desteği ve yeni özellikler eklemek için daha fazla bakım. Kullanıcılar tarafından bildirilen sorunların düzeltilmesini de gerektirebilir. | Etkileşimlerin çoğu huggingface_hub içinde uygulandığı için daha az bakım gerektirir. |
| Belgeler / Tip anotasyonu | Manuel olarak yazılacaktır. | Bunun bir kısmı huggingface_hub tarafından ele alınır. |
| İndirme sayacı | Manuel olarak ele alınacaktır. | Sınıfın bir config özniteliği varsa varsayılan olarak etkinleştirilir. |
| Model kartı | Manuel olarak ele alınacaktır | Varsayılan olarak library_name, tags vb. ile oluşturulur. |