Hub documentation
Panduan Webhook: Memproses file baru di bucket dengan Jobs
Panduan Webhook: Memproses file baru di bucket dengan Jobs
Storage Buckets adalah tempat yang baik untuk file yang tiba seiring waktu: ekspor dari alat lain, log, rekaman, hasil pemindaian. Anda sering kali akan memiliki alur kerja yang perlu dilakukan pada file-file ini sebelum mereka berguna, seperti mengonversi, membersihkan, atau mentranskripsikannya.
Webhook pada bucket dan Job dapat melakukan pekerjaan ini secara otomatis, tanpa server. Ketika file berubah, webhook memulai Job. Job menerima daftar file yang berubah, memprosesnya, dan berhenti. Anda hanya membayar selama Job berjalan.
Panduan ini menjelaskan polanya, lalu mengonfigurasikannya dengan satu contoh: mengonversi file CSV dan JSON yang diunggah menjadi Parquet yang dioptimalkan.
Cara kerjanya
file uploaded ──▶ webhook ──▶ Job runs with the event ──▶ result written to a second bucket
Webhook dapat memicu Job alih-alih memanggil URL. Anda membuat Job sekali, dan setiap event webhook akan menjalankannya kembali dengan event tersebut di lingkungannya. Untuk bucket, WEBHOOK_PAYLOAD mencantumkan file yang berubah:
{
"event": { "action": "update", "scope": "repo.content" },
"repo": { "type": "bucket", "name": "your-username/my-raw-files", ... },
"updatedFiles": [
{ "path": "data.csv", "action": "add", "xetHash": "433b53b8...", "size": 10983 }
]
}Jadi, Job hanya memproses file-file baru, dan dapat memutuskan cara menangani masing-masing file sebelum mengunduh apa pun.
Setiap run menggunakan ulang image, command, variabel lingkungan, hardware flavor, dan timeout dari Job. Run tidak mendapatkan volume atau secrets dari Job. Itulah mengapa langkah-langkah di bawah menjalankan script dari URL dan menempatkan token pada webhook.
Job menulis hasilnya ke bucket kedua. Jika Job menulis ke bucket yang dipantaunya, outputnya sendiri akan memicu webhook lagi.
Contoh: ubah unggahan menjadi Parquet yang dioptimalkan
Ekspor CSV dan JSON lambat untuk dikueri dan tidak nyaman untuk dibagikan. Parquet yang dioptimalkan lebih cepat untuk difilter dan distream, serta lebih cepat diunggah dan diunduh berkat deduplikasi Xet. Dalam contoh ini, setiap file CSV, JSON, atau Parquet yang diunggah ke satu bucket akan muncul sebagai Parquet yang dioptimalkan di bucket lain. Job menjalankan optimize-parquet.py, sebuah skrip siap pakai dari uv-scripts.
Anda memerlukan akun Hugging Face dengan kredit prabayar dan hf CLI.
Buat dua bucket
Satu bucket menerima unggahan Anda, dan bucket lainnya menerima file Parquet:
hf buckets create my-raw-files --private hf buckets create my-parquet --private
Buat Job
Buat Job yang akan dijalankan oleh webhook:
hf jobs run --flavor cpu-upgrade --timeout 2h \
-e OUTPUT_BUCKET=your-username/my-parquet \
ghcr.io/astral-sh/uv:python3.12-bookworm \
uv run https://huggingface.co/datasets/uv-scripts/data-processing/raw/main/optimize-parquet.pySkrip dijalankan dari URL-nya, dengan hf jobs run. hf jobs uv run adalah cara umum untuk menjalankan skrip UV, tetapi metode ini mengunggah skrip ke volume, yang tidak dimiliki oleh eksekusi webhook. cpu-upgrade sudah cukup untuk pekerjaan ini, dan batas waktu dua jam memberikan ruang untuk file berukuran besar.
Skrip juga dapat berada di bucket atau repo privat. Jangan gunakan bucket yang dipantau: mengunggah skrip akan memulai Job. Tambahkan --secrets HF_TOKEN ke perintah, dengan token yang dapat membaca skrip. Jika run gagal dengan SyntaxError, token tidak dapat membacanya. Token webhook membutuhkan akses yang sama, karena run webhook tidak mendapatkan secret ini.
hf jobs run memulai Job secara langsung. Eksekusi pertama ini tidak memiliki event webhook, dan optimize-parquet.py tidak melakukan apa-apa tanpa event tersebut, sehingga Job berhenti segera. Salin Job ID yang dicetak.
Buat webhook
Pantau bucket pertama dan jalankan Job Anda saat ada perubahan:
hf webhooks create --job-id <job ID> --watch bucket:your-username/my-raw-files \
--domain repo --secrets HF_TOKEN--domain repo membatasi webhook pada perubahan file dan pengaturan. Bucket hanya mengirim perubahan tersebut, sehingga opsi ini bersifat eksplisit alih-alih wajib, tetapi menjaga perintah tetap benar jika Anda kemudian memantau model atau dataset.
--secrets HF_TOKEN menyimpan token dengan webhook, dalam bentuk terenkripsi. Setiap Job yang dimulai oleh webhook akan menerimanya sebagai secret dan menggunakannya untuk membaca serta menulis bucket. Nilainya berasal dari HF_TOKEN di lingkungan Anda, atau dari token yang Anda gunakan saat login. token fine-grained yang hanya memiliki izin yang dibutuhkan Job adalah pilihan paling aman.
Untuk menggunakan token yang dibuat khusus untuk pipeline ini, berikan nilainya secara eksplisit dengan
--secrets HF_TOKEN=hf_…, atau simpan agar tidak masuk ke riwayat shell Anda dengan cara memipenya:printf 'HF_TOKEN=hf_…\n' | hf webhooks create … --secrets-file -.
Perintah ini mencetak ID webhook. Untuk menghentikan pipeline nanti, hapus webhook dengan hf webhooks delete <webhook ID>.
Unggah file
hf buckets cp data.csv hf://buckets/your-username/my-raw-files/data.csvSekitar satu menit kemudian, sebuah Job akan muncul di halaman Jobs Anda. Jika tidak ada, buka tab Activity dari webhook di pengaturan webhook Anda untuk melihat pengiriman, dan baca output Job dengan hf jobs logs <job ID>. Ketika Job selesai, file Parquet berada di bucket kedua:
hf buckets ls your-username/my-parquet -Rdata.csv/README.md data.csv/data/train-00000-of-00001.parquet
Untuk mengonversi banyak file, unggah semuanya dengan satu hf buckets sync. File yang diunggah bersama biasanya tiba sebagai satu event, sehingga satu Job mengonversi semuanya, hingga 10.000 file per event. Lihat Webhooks untuk payload bucket lengkap dan apa yang terjadi di atas batas tersebut.
Apa yang dilakukan oleh skrip
Bagian yang spesifik untuk webhook adalah membaca event:
event = json.loads(os.environ.get("WEBHOOK_PAYLOAD", "{}")) # empty when you run the Job yourself
input_bucket = os.environ.get("WEBHOOK_REPO_ID")
for changed_file in event.get("updatedFiles", []):
if changed_file["action"] != "add":
continue # skip deleted files
path, size = changed_file["path"], changed_file["size"]
... # convert the file (see the full script)Untuk setiap file baru, skrip memuatnya dengan datasets langsung dari bucket (hf://buckets/...). Jika file lebih besar dari sepertiga disk bebas Job, file tersebut di-stream alih-alih diunduh. push_to_hub kemudian menuliskannya ke bucket output sebagai Parquet dengan chunking yang didefinisikan konten, indeks halaman, dan grup baris maksimal 100 MB.
Gunakan pola untuk tugas Anda sendiri
Pertahankan setup dan ubah skripnya. Misalnya:
- Hapus data pribadi sebelum pelatihan. Kumpulkan teks mentah dalam bucket privat, redaksikan informasi pribadi dengan model seperti GLiNER2 PII filter, dan dorong hanya teks yang sudah diredaksi ke dataset pelatihan Anda.
- Evaluasi checkpoint baru. Job pelatihan menyimpan checkpoint ke bucket, dan setiap checkpoint baru memulai Job evaluasi. Jika sebuah checkpoint diunggah dalam beberapa bagian, hanya bereaksi ketika file penanda yang Anda tulis terakhir muncul di
updatedFiles; event dapat tiba secara tidak berurutan. - Transkripsi atau embed file baru. Ubah rekaman baru menjadi transkrip, atau dokumen baru menjadi embedding untuk pencarian.
Saat Anda menulis skrip, tentukan apa yang dilakukan pada eksekusi pertama, ketika WEBHOOK_PAYLOAD belum disetel. Skrip dapat keluar, seperti yang dilakukan optimize-parquet.py, atau melakukan pekerjaan nyata, seperti memproses file yang sudah ada di bucket. Jika eksekusi pertama memerlukan token, misalnya untuk membaca bucket atau skrip privat, tambahkan --secrets HF_TOKEN ke hf jobs run. Eksekusi webhook tidak menerima secret ini. Mereka mendapatkan token dari webhook.
Webhook atau jadwal?
Webhook memulai Job untuk setiap event, sehingga file baru diproses sekitar satu menit setelah tiba. Jika file tidak perlu diproses secepat itu, Job terjadwal adalah alternatifnya: Job ini berjalan setiap jam atau setiap hari dan memproses semua file yang tiba sejak eksekusi terakhir. Pendekatan ini mengelompokkan pekerjaan ke dalam lebih sedikit Job, yang membantu untuk tugas GPU yang lambat untuk dimulai, dan menghindari batas webhook 1.000 pemicu per 24 jam. Skrip kemudian harus menemukan file baru sendiri, misalnya dengan membandingkan bucket input dan output.
Update on GitHub