Hub Python Library documentation
إدارة مساحتك
إدارة مساحتك
في هذا الدليل، سنرى كيفية إدارة بيئة التشغيل الخاصة بمساحتك (الأسرار، العتاد، والأحجام) باستخدام huggingface_hub.
البحث عن مساحات
يمكنك البحث عن مساحات (Spaces) على Hub باستخدام البحث الدلالي عبر search_spaces(). يستخدم هذا البحث القائم على التضمينات (embeddings) للاستعلامات متعددة الكلمات، والبحث النصي الكامل للاستعلامات أحادية الكلمة.
>>> from huggingface_hub import search_spaces
>>> results = list(search_spaces("generate image"))
>>> results[0]
SpaceSearchResult(id='mrfakename/Z-Image-Turbo', title='Z Image Turbo', sdk='gradio', likes=2867, ...)يمكنك تصفية النتائج حسب SDK أو الوسوم:
>>> results = search_spaces("chatbot", sdk="gradio", filter="mcp-server")أو عبر سطر الأوامر:
>>> hf spaces search "generate image"
>>> hf spaces search "chatbot" --sdk gradio --limit 5مثال بسيط: تكوين الأسرار والأجهزة.
فيما يلي مثال شامل من البداية إلى النهاية لإنشاء مساحة على Hub وإعدادها.
إنشاء مساحة على الـ Hub
>>> from huggingface_hub import HfApi
>>> repo_id = "Wauplin/my-cool-training-space"
>>> api = HfApi()
# For example with a Gradio SDK
>>> api.create_repo(repo_id=repo_id, repo_type="space", space_sdk="gradio")مساحات Static مجانية للجميع. تعمل مساحات Gradio وDocker على وحدات معالجة: على العتاد المجاني
cpu-basic، تتطلب اشتراكًا (PRO للمستخدمين، أو Team أو Enterprise للمنظمات)، بينما يتطلب العتاد المدفوع فقط الفوترة (طريقة دفع وأرصدة مسبقة الدفع). بدون اشتراك، يفشل إنشاء مساحة Gradio أو Docker علىcpu-basicأو تكرارها أو نقلها بخطأ دفع (HTTP 402). راجع التسعير لمزيد من التفاصيل.
إنشاء مساحة من قالب
بدلاً من البدء من مساحة فارغة، يمكنك تهيئة مساحة جديدة من أحد القوالب الرسمية المعروضة على Hub (مثل JupyterLab، أو روبوت محادثة Gradio، أو تطبيق Streamlit، وما إلى ذلك). اذكر القوالب المتاحة باستخدام list_space_templates()، ثم مرّر repo_id للقالب (أو name المختصر له) كـ space_template إلى create_repo(). لاحظ أن space_sdk لا يزال مطلوباً: فالقالب يهيئ الملفات بينما يضبط SDK بيانات بطاقة الوصف.
>>> from huggingface_hub import HfApi
>>> api = HfApi()
# List available templates
>>> for template in api.list_space_templates():
... print(f"{template.name} ({template.repo_id})")
Streamlit (streamlit/streamlit-template-space)
JupyterLab (SpacesExamples/jupyterlab)
chatbot (gradio-templates/chatbot)
...
# Create a Space from a template, by repo id or by short name
>>> api.create_repo(repo_id=repo_id, repo_type="space", space_template="SpacesExamples/jupyterlab")
>>> api.create_repo(repo_id=repo_id, repo_type="space", space_template="JupyterLab")تُوصى بعض القوالب بأن تكون خاصة (مثل JupyterLab). إذا لم تضبط مستوى العرض بشكل صريح، فسيتم إنشاء هذه المساحات كخاصة تلقائيًا.
من سطر الأوامر، يتوفر الأمر نفسه عبر hf spaces templates وhf repos create --template:
# List available templates
>>> hf spaces templates
NAME REPO_ID SDK PREFERRED_PRIVATE
--------------- ---------------------------------------------- ------ -----------------
Streamlit streamlit/streamlit-template-space docker
JupyterLab SpacesExamples/jupyterlab docker ✔
Argilla argilla/argilla-template-space docker
Livebook livebook-dev/livebook docker
...
# Create a Space from a template
>>> hf repos create my-jupyterlab --type space --template jupyterlabنسخ مساحة
يمكن أن يكون ذلك مفيدًا إذا كنت ترغب في البناء انطلاقًا من مساحة (Space) موجودة مسبقًا بدلاً من البدء من الصفر. كما أنه مفيد إذا كنت ترغب في التحكم في إعدادات/إعدادات مساحة عامة. راجع duplicate_repo() لمزيد من التفاصيل.
>>> api.duplicate_repo("multimodalart/dreambooth-training", repo_type="space")ارفع كودك باستخدام الحل المفضل لديك
فيما يلي مثال لرفع المجلد المحلي src/ من جهازك إلى مساحتك:
>>> api.upload_folder(repo_id=repo_id, repo_type="space", folder_path="src/")في هذه الخطوة، يجب أن يكون تطبيقك يعمل بالفعل على الـ Hub! ومع ذلك، قد ترغب في تكوينه بشكل أكبر باستخدام الأسرار (secrets) وعتاد (hardware) محسّن.
إعداد الأسرار والمتغيرات
قد تتطلب مساحة بعض المفاتيح السرية أو الرموز أو المتغيرات لتعمل. راجع التوثيق لمزيد من التفاصيل. على سبيل المثال، رمز HF لرفع مجموعة بيانات الصور إلى Hub بعد توليدها من مساحتك.
>>> api.add_space_secret(repo_id=repo_id, key="HF_TOKEN", value="hf_api_***")
>>> api.add_space_variable(repo_id=repo_id, key="MODEL_REPO_ID", value="user/repo")يمكنك سرد الأسرار والمتغيرات الموجودة. قيم الأسرار قابلة للكتابة فقط، لذا تُعاد المفاتيح والوصوف وطوابع التحديث الزمنية فقط:
>>> api.get_space_secrets(repo_id=repo_id)
{'HF_TOKEN': SpaceSecret(key='HF_TOKEN', description=None, updated_at=datetime.datetime(...))}
>>> api.get_space_variables(repo_id=repo_id)
{'MODEL_REPO_ID': SpaceVariable(key='MODEL_REPO_ID', value='user/repo', description=None, updated_at=...)}يمكن أيضًا حذف الأسرار والمتغيرات:
>>> api.delete_space_secret(repo_id=repo_id, key="HF_TOKEN")
>>> api.delete_space_variable(repo_id=repo_id, key="MODEL_REPO_ID")من داخل مساحتك، تتوفر الأسرار كمتغيرات بيئة (أو إدارة أسرار Streamlit إذا كنت تستخدم Streamlit). لا حاجة لجلبها عبر واجهة برمجة التطبيقات!
أي تغيير في إعدادات مساحة العمل الخاصة بك (الأسرار أو العتاد) سيؤدي إلى إعادة تشغيل تطبيقك.
مكافأة: اضبط الأسرار والمتغيرات عند إنشاء مساحة أو تكرارها!
يمكن تعيين الأسرار والمتغيرات عند إنشاء مساحة أو تكرارها:
>>> api.create_repo(
... repo_id=repo_id,
... repo_type="space",
... space_sdk="gradio",
... space_secrets=[{"key": "HF_TOKEN", "value": "hf_api_***"}, ...],
... space_variables=[{"key": "MODEL_REPO_ID", "value": "user/repo"}, ...],
... )>>> api.duplicate_repo(
... from_id=repo_id,
... repo_type="space",
... space_secrets=[{"key": "HF_TOKEN", "value": "hf_api_***"}, ...],
... space_variables=[{"key": "MODEL_REPO_ID", "value": "user/repo"}, ...],
... )تهيئة العتاد
بشكل افتراضي، يعمل مساحتك على العتاد المجاني cpu-basic (والذي يتطلب اشتراكًا لمساحات Gradio وDocker، انظر أعلاه). يمكنك ترقية العتاد لتشغيله على وحدات معالجة الرسومات. يتطلب ترقية مساحتك وجود طريقة دفع ورسوم مسبقة الدفع (أو منحة مجتمعية). راجع التوثيق لمزيد من التفاصيل.
# Use `SpaceHardware` enum
>>> from huggingface_hub import SpaceHardware
>>> api.request_space_hardware(repo_id=repo_id, hardware=SpaceHardware.T4_MEDIUM)
# Or simply pass a string value
>>> api.request_space_hardware(repo_id=repo_id, hardware="t4-medium")لا يتم تحديث العتاد فورًا، إذ يجب إعادة تحميل مساحتك على خوادمنا. في أي وقت، يمكنك التحقق من العتاد الذي تعمل عليه مساحتك لمعرفة ما إذا كان طلبك قد تم تنفيذه.
>>> runtime = api.get_space_runtime(repo_id=repo_id)
>>> runtime.stage
"RUNNING_BUILDING"
>>> runtime.hardware
"cpu-basic"
>>> runtime.requested_hardware
"t4-medium"لديك الآن مساحة مُهيأة بالكامل. تأكد من تخفيض مساحة عملك إلى cpu-basic عند الانتهاء من استخدامها.
مكافأة: اطلب العتاد عند إنشاء المساحة أو تكرارها!
سيتم تعيين الأجهزة المُحدَّثة تلقائيًا إلى مساحتك بمجرد اكتمال بنائها.
>>> api.create_repo(
... repo_id=repo_id,
... repo_type="space",
... space_sdk="gradio",
... space_hardware="cpu-upgrade",
... space_sleep_time="7200", # 2 hours in secs
... )>>> api.duplicate_repo(
... from_id=repo_id,
... repo_type="space",
... space_hardware="cpu-upgrade",
... space_sleep_time="7200", # 2 hours in secs
... )تتبع حصة ZeroGPU الخاصة بك
تعمل مساحات ZeroGPU على وحدات معالجة رسومية مشتركة تُخصَّص عند الطلب. في كل مرة تستخدم فيها مساحة ZeroGPU (سواءً من واجهة المستخدم أو عبر واجهتها البرمجية)، يُخصم بعض وقت وحدة المعالجة الرسومية من حصتك الشخصية، والتي تُعاد ضبطها دوريًا. إذا كنت تبني تطبيقًا أو وكيلًا أو خادم MCP فوق مساحات ZeroGPU، يمكنك تتبع استخدامك عبر get_zero_gpu_quota(). تُعبَّر القيم بالثواني الرسومية (GPU-seconds).
>>> quota = api.get_zero_gpu_quota()
>>> quota
ZeroGpuQuota(base=2400, remaining=1810, resets_at=datetime.datetime(2026, 9, 30, 9, 12, 3, tzinfo=datetime.timezone.utc), overquota_used=0)
>>> if quota.remaining < 60:
... print(f"Less than 1 minute of ZeroGPU left. Quota resets at {quota.resets_at}.")resets_at تكون None إذا لم تكن قد استخدمت ZeroGPU منذ آخر إعادة تعيين. إذا كنت تستخدم رمزًا دقيقًا، فيجب أن يكون لديه إذن “Billing > Read billing usage and payment method status”. تتوفر نفس المعلومات من سطر الأوامر باستخدام hf spaces zero-gpu quota.
بمجرد استنفاد الحصة، يمكن للمستخدمين من فئات PRO وTeam وEnterprise مواصلة استخدام مساحات ZeroGPU من خلال استهلاك الرصيد المدفوع مسبقًا. يمكنك شراء الرصيد من إعدادات الفوترة. راجع تمديد الحصة باستخدام الرصيد لمزيد من التفاصيل.
إيقاف مساحة عملك مؤقتاً وإعادة تشغيلها
بشكل افتراضي، إذا كان مساحتك تعمل على أجهزة مادية مُحدَّثة، فلن يتم إيقافها أبدًا. ومع ذلك، لتجنب دفع الفواتير، قد ترغب في إيقافها مؤقتًا عندما لا تكون مستخدماً لها. وهذا ممكن باستخدام pause_space(). ستكون المساحة الموقوفة مؤقتًا غير نشطة حتى يعيد مالك المساحة تشغيلها، إما عبر واجهة المستخدم أو عبر واجهة برمجة التطبيقات باستخدام restart_space(). لمزيد من التفاصيل حول الوضع الموقوف مؤقتًا، يرجى الرجوع إلى هذا القسم
# Pause your Space to avoid getting billed
>>> api.pause_space(repo_id=repo_id)
# (...)
# Restart it when you need it
>>> api.restart_space(repo_id=repo_id)إحدى الاحتمالات الأخرى هي ضبط مهلة زمنية لمساحتك. إذا كانت مساحتك غير نشطة لفترة تتجاوز مدة المهلة، فستدخل في وضع السكون. أي زائر يصل إلى مساحتك سيعيد تشغيلها. يمكنك ضبط مهلة باستخدام set_space_sleep_time(). لمزيد من التفاصيل حول وضع السكون، يرجى الرجوع إلى هذا القسم.
# Put your Space to sleep after 1h of inactivity
>>> api.set_space_sleep_time(repo_id=repo_id, sleep_time=3600)ملاحظة: إذا كنت تستخدم عتادًا من نوع ‘cpu-basic’، فلا يمكنك ضبط وقت سكون مخصص. سيتم إيقاف مساحة عملك تلقائيًا بعد 48 ساعة من عدم النشاط.
مكافأة: تحديد وقت للنوم أثناء طلب العتاد
سيتم تعيين الأجهزة المُحدَّثة تلقائيًا إلى مساحتك بمجرد اكتمال بنائها.
>>> api.request_space_hardware(repo_id=repo_id, hardware=SpaceHardware.T4_MEDIUM, sleep_time=3600)مكافأة: اضبط وقتًا للنوم عند إنشاء مساحة أو تكرارها!
>>> api.create_repo(
... repo_id=repo_id,
... repo_type="space",
... space_sdk="gradio",
... space_hardware="t4-medium",
... space_sleep_time="3600",
... )>>> api.duplicate_repo(
... from_id=repo_id,
... repo_type="space",
... space_hardware="t4-medium",
... space_sleep_time="3600",
... )استكشاف الأخطاء وإصلاحها في مساحة (Space) غير ناجحة من خلال قراءة سجلاتها
عندما يفشل بناء مساحة أو ينهار أثناء التشغيل، تكون السجلات التي تعرضها عادةً في المتصفح متاحة أيضاً برمجياً عبر fetch_space_logs(). وهذا مفيد بشكل خاص من السكربتات أو سير العمل الوكيلية حيث لا يكون فتح المتصفح خياراً متاحاً.
# Drain the currently available run logs and return immediately (like `docker logs`)
>>> for line in api.fetch_space_logs(repo_id=repo_id):
... print(line, end="")
# Read the container build logs instead (useful when the Space is stuck in BUILD_ERROR)
>>> for line in api.fetch_space_logs(repo_id=repo_id, build=True):
... print(line, end="")
# Stream run logs in real time until the server closes the stream (Ctrl-C to stop)
>>> for line in api.fetch_space_logs(repo_id=repo_id, follow=True):
... print(line, end="")يتوفر نفس الوظيفية من سطر الأوامر:
hf spaces logs username/my-space # drain run logs
hf spaces logs username/my-space --build # read build logs
hf spaces logs username/my-space -f # stream in real time
hf spaces logs username/my-space -n 50 # last 50 lines onlyالاتصال عبر SSH بمساحة (وضع التطوير)
يتيح لك وضع التطوير الدخول عبر SSH إلى حاوية مساحة قيد التشغيل للتحسين المباشر والتطوير. استخدم hf spaces ssh لفتح جلسة مباشرة من الطرفية. إذا لم يكن وضع التطوير مفعّلًا بعد على المساحة، فسيطلب منك سطر الأوامر تفعيله (أو مرّر --auto لتخطي الطلب).
يجب تسجيل مفتاح SSH العام الخاص بك في إعداداتك.
# SSH into a Space (enables Dev Mode if needed)
hf spaces ssh username/my-space
# Auto-enable Dev Mode without prompting
hf spaces ssh username/my-space --auto
# Print the SSH command without running it
hf spaces ssh username/my-space --dry-run
# Use a specific SSH key
hf spaces ssh username/my-space -i ~/.ssh/id_ed25519يمكنك أيضًا تفعيل وضع التطوير دون استخدام SSH باستخدام hf spaces dev-mode، والذي يطبع تعليمات الاتصال لـ SSH وVS Code وCursor وWindsurf:
hf spaces dev-mode username/my-space
يتطلب تفعيل وضع المطوّر اشتراكًا بخطة PRO أو خطة Team & Enterprise. يُسمح دائمًا بإيقافه، على سبيل المثال إذا انتهت صلاحية اشتراكك بينما كان وضع المطوّر مفعّلًا:
hf spaces dev-mode username/my-space --stop
تثبيت الأحجام في مساحتك
يمكنك تثبيت موارد Hub (النماذج، مجموعات البيانات، أو دلاء التخزين) كمجلدات في حاوية مساحة العمل الخاصة بك. يمنح ذلك مساحة العمل الخاصة بك وصولاً مباشراً إلى نظام الملفات لهذه الموارد دون الحاجة إلى تنزيلها في الكود الخاص بك. يمكن تعيين المجلدات مباشرةً عند إنشاء مساحة العمل أو تكرارها:
>>> from huggingface_hub import Volume
>>> api.create_repo(
... repo_id=repo_id,
... repo_type="space",
... space_sdk="gradio",
... space_volumes=[
... Volume(type="model", source="username/my-model", mount_path="/models", read_only=True),
... Volume(type="bucket", source="username/my-bucket", mount_path="/data"),
... ],
... )>>> api.duplicate_repo(
... from_id=repo_id,
... repo_type="space",
... space_volumes=[
... Volume(type="model", source="username/my-model", mount_path="/models", read_only=True),
... Volume(type="bucket", source="username/my-bucket", mount_path="/data"),
... ],
... )يمكنك التحقق من الأحجام (volumes) المثبتة حاليًا عبر بيئة تشغيل المساحة (Space runtime):
>>> runtime = api.get_space_runtime(repo_id=repo_id)
>>> runtime.volumes
[Volume(type='model', source='username/my-model', mount_path='/models', read_only=True), ...]إذا كنت بحاجة إلى تحديث الأحجام على مساحة موجودة مسبقًا، فاستخدم set_space_volumes(). لاحظ أن هذا يستبدل جميع الأحجام المثبتة سابقًا.
>>> api.set_space_volumes(
... repo_id=repo_id,
... volumes=[
... Volume(type="model", source="username/my-model", mount_path="/models", read_only=True),
... Volume(type="dataset", source="username/my-dataset", mount_path="/data", read_only=True),
... Volume(type="bucket", source="username/my-bucket", mount_path="/output"),
... ],
... )لإزالة جميع الأحجام من مساحتك:
>>> api.delete_space_volumes(repo_id=repo_id)تُركَّب النماذج ومجموعات البيانات ومساحات العمل دائمًا للقراءة فقط. لا تدعم حاويات التخزين سوى التركيب للقراءة والكتابة.
استبدال الأحجام يحل محل أي أحجام كانت معلقة سابقًا. لإضافة حجم إلى قائمة قائمة بالفعل، اقرأ أولًا الأحجام الحالية من وقت التشغيل وشملها في القائمة الجديدة.
جميع عمليات التخزين المتوفرة أيضاً من سطر الأوامر:
# List current volumes
hf spaces volumes ls username/my-space
# Set (replace) volumes
hf spaces volumes set username/my-space \
-v hf://models/username/my-model:/models \
-v hf://buckets/username/my-bucket:/data
# Remove all volumes
hf spaces volumes delete username/my-spaceللمتقدمين: قم بترقية مساحة عملك مؤقتًا!
تتيح Spaces العديد من حالات الاستخدام المختلفة. في بعض الأحيان، قد ترغب في تشغيل مساحة مؤقتًا على عتاد محدد، وإجراء مهمة ما ثم إيقافها. في هذا القسم، سنستكشف كيفية الاستفادة من Spaces لضبط نموذج حسب الطلب. هذه ليست سوى طريقة واحدة لحل هذه المشكلة بالتحديد. يجب النظر إليها كتوصية وتكييفها لتناسب حالة الاستخدام الخاصة بك.
لنفترض أن لدينا مساحة (Space) لضبط نموذج. إنها تطبيق Gradio يستقبل كمُدخلات معرّف نموذج ومعرّف مجموعة بيانات. سير العمل هو على النحو التالي:
- (اطلب من المستخدم تحديد نموذج ومجموعة بيانات)
- حمّل النموذج من Hub.
- قم بتحميل مجموعة البيانات من Hub.
- قم بضبط نموذجك على مجموعة البيانات.
- ارفع النموذج الجديد إلى Hub.
Step 3. requires a custom hardware but you don’t want your Space to be running all the time on a paid GPU. A solution is to dynamically request hardware for the training and shut it down afterwards. Since requesting hardware restarts your Space, your app must somehow “remember” the current task it is performing. There are multiple ways of doing this. In this guide we will see one solution using a Dataset as “task scheduler”.
هيكل التطبيق
إليك الشكل الذي ستبدو عليه تطبيقك. عند الإقلاع، تحقق مما إذا كان هناك مهمة مجدولة، وإذا كان الأمر كذلك، نفّذها على العتاد الصحيح. بمجرد الانتهاء، أعد ضبط العتاد إلى وحدة المعالجة المركزية cpu-basic المتاحة، واطلب من المستخدم مهمة جديدة.
لا يدعم هذا سير العمل الوصول المتزامن كما هو الحال في العروض التوضيحية العادية. على وجه التحديد، سيتم تعطيل الواجهة عند حدوث التدريب. يُفضَّل تعيين مستودعك كخاص للتأكد من أنك المستخدم الوحيد.
# Space will need your token to request hardware: set it as a Secret !
HF_TOKEN = os.environ.get("HF_TOKEN")
# Space own repo_id
TRAINING_SPACE_ID = "Wauplin/dreambooth-training"
from huggingface_hub import HfApi, SpaceHardware
api = HfApi(token=HF_TOKEN)
# On Space startup, check if a task is scheduled. If yes, finetune the model. If not,
# display an interface to request a new task.
task = get_task()
if task is None:
# Start Gradio app
def gradio_fn(task):
# On user request, add task and request hardware
add_task(task)
api.request_space_hardware(repo_id=TRAINING_SPACE_ID, hardware=SpaceHardware.T4_MEDIUM)
gr.Interface(fn=gradio_fn, ...).launch()
else:
runtime = api.get_space_runtime(repo_id=TRAINING_SPACE_ID)
# Check if Space is loaded with a GPU.
if runtime.hardware == SpaceHardware.T4_MEDIUM:
# If yes, finetune base model on dataset !
train_and_upload(task)
# Then, mark the task as "DONE"
mark_as_done(task)
# DO NOT FORGET: set back CPU hardware
api.request_space_hardware(repo_id=TRAINING_SPACE_ID, hardware=SpaceHardware.CPU_BASIC)
else:
api.request_space_hardware(repo_id=TRAINING_SPACE_ID, hardware=SpaceHardware.T4_MEDIUM)جدولة المهام
يمكن تنفيذ جدولة المهام بعدة طرق. فيما يلي مثال على كيفية القيام بذلك باستخدام ملف CSV بسيط مخزّن كـ Dataset.
# Dataset ID in which a `tasks.csv` file contains the tasks to perform.
# Here is a basic example for `tasks.csv` containing inputs (base model and dataset)
# and status (PENDING or DONE).
# multimodalart/sd-fine-tunable,Wauplin/concept-1,DONE
# multimodalart/sd-fine-tunable,Wauplin/concept-2,PENDING
TASK_DATASET_ID = "Wauplin/dreambooth-task-scheduler"
def _get_csv_file():
return hf_hub_download(repo_id=TASK_DATASET_ID, filename="tasks.csv", repo_type="dataset", token=HF_TOKEN)
def get_task():
with open(_get_csv_file()) as csv_file:
csv_reader = csv.reader(csv_file, delimiter=',')
for row in csv_reader:
if row[2] == "PENDING":
return row[0], row[1] # model_id, dataset_id
def add_task(task):
model_id, dataset_id = task
with open(_get_csv_file()) as csv_file:
with open(csv_file, "r") as f:
tasks = f.read()
api.upload_file(
repo_id=repo_id,
repo_type=repo_type,
path_in_repo="tasks.csv",
# Quick and dirty way to add a task
path_or_fileobj=(tasks + f"\n{model_id},{dataset_id},PENDING").encode()
)
def mark_as_done(task):
model_id, dataset_id = task
with open(_get_csv_file()) as csv_file:
with open(csv_file, "r") as f:
tasks = f.read()
api.upload_file(
repo_id=repo_id,
repo_type=repo_type,
path_in_repo="tasks.csv",
# Quick and dirty way to set the task as DONE
path_or_fileobj=tasks.replace(
f"{model_id},{dataset_id},PENDING",
f"{model_id},{dataset_id},DONE"
).encode()
)