From d1efc21baad487f9c062d7155c48ab1ef3617847 Mon Sep 17 00:00:00 2001 From: Daniel van Strien Date: Fri, 30 Oct 2026 13:45:28 +0000 Subject: [PATCH 01/10] Add Run on Jobs Space generated from the recipes A static catalogue of recipes with first-run examples, a searchable list of models and copy-paste commands. tools/build-catalog.py generates the Space files, recipes.json and AGENTS.md by parsing the scripts without running them. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016isSPpM5PRqNUzwsDntoG4 --- .github/workflows/check-run-on-jobs.yml | 18 + .github/workflows/sync-run-on-jobs.yml | 15 + run-on-jobs/AGENTS.md | 22 + run-on-jobs/README.md | 42 ++ run-on-jobs/assets/nasa-food-list.jpg | Bin 0 -> 106447 bytes run-on-jobs/index.html | 376 +++++++++++ run-on-jobs/recipes.json | 796 ++++++++++++++++++++++++ tools/build-catalog.py | 395 ++++++++++++ tools/run-on-jobs-template.html | 290 +++++++++ 9 files changed, 1954 insertions(+) create mode 100644 .github/workflows/check-run-on-jobs.yml create mode 100644 .github/workflows/sync-run-on-jobs.yml create mode 100644 run-on-jobs/AGENTS.md create mode 100644 run-on-jobs/README.md create mode 100644 run-on-jobs/assets/nasa-food-list.jpg create mode 100644 run-on-jobs/index.html create mode 100644 run-on-jobs/recipes.json create mode 100644 tools/build-catalog.py create mode 100644 tools/run-on-jobs-template.html diff --git a/.github/workflows/check-run-on-jobs.yml b/.github/workflows/check-run-on-jobs.yml new file mode 100644 index 0000000..4b646b2 --- /dev/null +++ b/.github/workflows/check-run-on-jobs.yml @@ -0,0 +1,18 @@ +name: Check run-on-jobs catalogue +# Fails when a recipe changes without rebuilding the Space, or when a declared model leaves the Hub. +on: + pull_request: + schedule: + - cron: '0 7 * * 1' + workflow_dispatch: + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.12' + - name: Space files match the recipes, and declared models exist + run: python3 tools/build-catalog.py --check --verify-models diff --git a/.github/workflows/sync-run-on-jobs.yml b/.github/workflows/sync-run-on-jobs.yml new file mode 100644 index 0000000..5f3db9c --- /dev/null +++ b/.github/workflows/sync-run-on-jobs.yml @@ -0,0 +1,15 @@ +name: Sync run-on-jobs → HF +on: + push: + branches: [main] + paths: ['run-on-jobs/**', '.github/workflows/sync-run-on-jobs.yml'] + +jobs: + sync: + uses: ./.github/workflows/_sync-folder.yml + with: + folder: run-on-jobs + repo_id: uv-scripts/run-on-jobs + repo_type: space + secrets: + HF_TOKEN: ${{ secrets.HF_TOKEN }} diff --git a/run-on-jobs/AGENTS.md b/run-on-jobs/AGENTS.md new file mode 100644 index 0000000..b19686d --- /dev/null +++ b/run-on-jobs/AGENTS.md @@ -0,0 +1,22 @@ +# Run a model on Hugging Face Jobs + +`recipes.json` lists one-command batch recipes. Find the model in `recipes[].models`. + + hf download uv-scripts/run-on-jobs recipes.json --repo-type space + +Each recipe has: + +- `kind`: `run` applies a model to data; `train` fine-tunes one. +- `command`: the command to start from. `INPUT` and `OUTPUT` are usually dataset IDs; read the script to confirm. +- `source`: how far to trust the command. + - `header`: the script carries its launch settings. + - `documented`: an example from the script's docs. It may set its own hardware flags. + - `flags-needed`: `command` is null. Read the script and choose the options yourself. + +Before you start a job: + +1. Read the options: open the recipe's `url`. +2. Preview without spending: `hf jobs uv run --dry-run `. Check the image and flavor; without a header a GPU recipe can resolve to `cpu-basic`. +3. Start small: pass `--max-samples` if the script has it. +4. Monitor: `hf jobs ps`, `hf jobs logs `. +5. Check the output. A completed job is not proof that its rows are correct. diff --git a/run-on-jobs/README.md b/run-on-jobs/README.md new file mode 100644 index 0000000..6d72c9c --- /dev/null +++ b/run-on-jobs/README.md @@ -0,0 +1,42 @@ +--- +title: Run on Jobs +emoji: ⚡ +colorFrom: blue +colorTo: gray +sdk: static +pinned: false +short_description: Run this model over your own data on HF Jobs +models: + - allenai/olmOCR-2-7B-1025-FP8 + - ATH-MaaS/OvisOCR2 + - baidu/Qianfan-OCR + - baidu/Unlimited-OCR + - baidu/Unlimited-OCR-2 + - datalab-to/lift + - datalab-to/surya-ocr-2 + - deepseek-ai/DeepSeek-OCR + - deepseek-ai/DeepSeek-OCR-2 + - facebook/sam3 + - fastino/gliner2.5-multi-v1 + - HuggingFaceTB/SmolLM3-3B + - lightonai/LightOnOCR-2-1B + - lightonai/LightOnOCR-3-4B + - NemoStation/Marlin-2B + - numind/NuExtract3 + - nvidia/NVIDIA-Nemotron-3.5-Transcribe-30B-A4B + - PaddlePaddle/PaddleOCR-VL-1.6 + - Qwen/Qwen2-VL-7B-Instruct + - Qwen/Qwen3.6-35B-A3B + - Qwen/Qwen3.8-27B + - rednote-hilab/dots.mocr + - rednote-hilab/dots.ocr + - sentence-transformers/all-MiniLM-L6-v2 + - tencent/HunyuanOCR + - zai-org/GLM-OCR +--- + +# Run on Jobs + +A catalogue of [uv-scripts](https://huggingface.co/uv-scripts) recipes: one command runs a model over your own data on [Hugging Face Jobs](https://huggingface.co/docs/hub/jobs). + +This Space is generated from [davanstrien/uv-scripts](https://github.com/davanstrien/uv-scripts). To change it, edit the recipes or `tools/build-catalog.py` there. Agents should read [AGENTS.md](./AGENTS.md). diff --git a/run-on-jobs/assets/nasa-food-list.jpg b/run-on-jobs/assets/nasa-food-list.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6448539b755d77758aae638a62b57aa204a397ed GIT binary patch literal 106447 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 G+5ZA1R0wbY literal 0 HcmV?d00001 diff --git a/run-on-jobs/index.html b/run-on-jobs/index.html new file mode 100644 index 0000000..64fe801 --- /dev/null +++ b/run-on-jobs/index.html @@ -0,0 +1,376 @@ + + + + + +Run on Jobs + + + + + +
+

Run Hub models on your own data

+

One command starts a GPU on Hugging Face Jobs, runs the model over your whole dataset and saves the results to the Hub. There is nothing to clone.

+
+
+

Read seven scanned NASA pages with GLM-OCR and save the text to a new dataset on your account.

hf jobs uv run \
+    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/glm-ocr.py \
+    uv-scripts/ocr-demo your-username/ocr-demo-results
The scan
Scanned page listing Space Shuttle foods
What the Job wrote
Space Shuttle Food and Beverage List
+
+Foods*
+
+Applesauce (T)
+Apricots, dried (IM)
+Asparagus (R)
+Bananas (FD)
+Beef almondine (R)
+Beef, corned (I) (T)
+Beef and gravy (T)
+Beef, ground w/pickle sauce (T)
+Beef jerky (IM)
+Beef patty (R)
+Beef, slices w/barbeque sauce (T)
+Beef steak (I) (T)
+Beef stroganoff w/noodles (R)
+Bread, seedless rye (I) (NF)
+Broccoli au gratin (R)
+Breakfast roll (I) (NF)
+Candy, Life Savers*, assorted flavors (NF)
+Cauliflower w/cheese (R)
+Cereal, bran flakes (R)
+Cereal, cornflakes (R)
+Cereal, granola (R)
+Cereal, granola w/blueberries (R)
+Cereal, granola w/raisins (R)
+Cheddar cheese spread (T)
+Chicken a la king (T)
+
+Chicken and noodles (R)
+Chicken and rice (R)
+Chili mac w/beef (R)
+Cookies, pecan (NF)
+Cookies, shortbread (NF)
+Crackers, graham (NF)
+Eggs, scrambled (R)
+Food bar, almond crunch (NF)
+Food bar, chocolate chip (NF)
+Food bar, granola (NF)
+Food bar, granola/raisin (NF)
+Food bar, peanut butter/granola (NF)
+Frankfurters (Vienna sausage) (T)
+Fruitcake (NF)
+Fruit cocktail (T)
+Green beans, french w/mushrooms (R)
+Green beans and broccoli (R)
+Ham (I) (T)
+Jam/Jelly (T)
+Macaroni and cheese (R)
+Meatballs w/barbeque sauce (T)
+Nuts, almonds (NF)
+Nuts, cashews (NF)
+Nuts, peanuts (NF)
+
+Peach ambrosia (R)
+Peaches, dried (IM)
+Peaches, (T)
+Peanut butter
+Pears (FD)
+Pears (T)
+Peas w/butter sauce (R)
+Pineapple, crushed (T)
+Pudding, butterscotch (T)
+Pudding, chocolate (R) (T)
+Pudding, lemon (T)
+Pudding, vanilla (R) (T)
+Rice pilaf (R)
+Salmon (T)
+Sausage patty (R)
+Shrimp creole (R)
+Shrimp cocktail (R)
+Soup, cream of mushroom (R)
+Spaghetti w/meatless sauce (R)
+Strawberries (R)
+Tomatoes, stewed (T)
+Tuna (T)
+Turkey and gravy (T)
+Turkey, smoked/sliced (I) (T)
+Turkey tetrazzini (R)
+Vegetables, mixed Italian (R)
+
+Beverages
+
+Apple drink
+Cocoa
+Coffee, black
+Coffee w/cream
+Coffee w/cream and sugar
+Coffee w/sugar
+Grape drink
+Grapefruit drink
+Instant breakfast, chocolate
+Instant breakfast, strawberry
+
+Instant breakfast, vanilla
+Lemonade
+Orange drink
+Orange-grapefruit drink
+Orange-pineapple drink
+Strawberry drink
+Tea
+Tea w/lemon and sugar
+Tea w/sugar
+Tropical punch
+
+Condiments
+
+Barbeque sauce
+Catsup
+Mustard
+Pepper
+Salt
+Hot pepper sauce
+Mayonnaise
+
+*Abbreviations in parentheses indicate type of food T = thermostabilized, I = irradiated, IM = intermediate moisture, FD = freeze dried, R = rehydratable, and NF = natural form.
+
+Shuttle Menu
+
+The Space Shuttle menu currently features more than 70 food items and 20 beverages. Shuttle travelers will have a varied menu every day for six days rather than the personal preference meals used in previous space missions. Each day, three meals are allowed, with a repeat of menus after six days. The pantry also provides plenty of foods for snacks and between meal beverages and for individual menu changes. The pantry also stores additional contingency food to last 96 hours.
+
+Food System Constraints
+
+The primary objective in designing a food system for the Space Shuttle is to provide food that is safe and nutritious, light in weight and compact, and is packaged in a convenient form that allows easy manipulation in the weightless environment of an orbiting spacecraft. To achieve this objective requires a careful consideration of three important factors: biological, operational, and engineering. Under each factor are many constraints that affect the final choice of food and how it is

Our run: davanstrien/ocr-demo-results. 7 pages, 2.4 minutes of processing on a10g-small, after a few minutes of setup.

+

Transcribe four minutes of a NASA podcast, with speaker tags and word timestamps, into your own Bucket.

hf buckets create your-username/transcripts --private
+hf jobs uv run --timeout 45m \
+    -v hf://buckets/uv-scripts/transcription-demo/podcast:/input:ro \
+    -v hf://buckets/your-username/transcripts/podcast:/output \
+    https://huggingface.co/datasets/uv-scripts/transcription/raw/main/nemotron-transcribe.py \
+    /input /output --timestamps
<spk:0> Jim, thank you so much for coming on the podcast today. ... <spk:3> It is, uh, the mission control room, of course, is now open for business ...

Our run: about 7.5 minutes on rtx-pro-6000, about $0.34. Most of that was model setup.

+

Embed the first 100 IMDb reviews and save them as a private dataset.

hf jobs uv run --flavor l4x1 -s HF_TOKEN \
+    https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/generate-embeddings.py \
+    stanfordnlp/imdb your-username/imdb-embeddings \
+    --column text --max-samples 100 --private

One L4 GPU embeds about 900 rows per second with all-MiniLM-L6-v2.

+
+

You need the hf CLI (1.32 or newer), a login and pay-as-you-go credit. Add --dry-run to see the GPU and settings without starting a job.

+

Find your model

+

In the commands, INPUT and OUTPUT are dataset IDs unless the recipe says otherwise.

+ + + +

OCR

  • allenai/olmOCR-2-7B-1025-FP8ready · a10g-small

    olmocr2-vllm.py ready to run · a10g-small

    Convert document images to markdown using olmOCR-2 with vLLM.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/olmocr2-vllm.py \
    +    INPUT_DATASET OUTPUT_DATASET
  • ATH-MaaS/OvisOCR2ready · a10g-small

    ovis-ocr2.py ready to run · a10g-small

    Convert document images to markdown using OvisOCR2 with vLLM.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/ovis-ocr2.py \
    +    INPUT_DATASET OUTPUT_DATASET
    1 more recipe

    ovis-ocr2-saturate.py ready to run · a10g-small

    Convert document images to markdown using OvisOCR2 via saturate.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/ovis-ocr2-saturate.py \
    +    INPUT_DATASET OUTPUT_DATASET
  • baidu/Qianfan-OCRready · a10g-small

    qianfan-ocr.py ready to run · a10g-small

    Convert document images to markdown using Qianfan-OCR with vLLM.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/qianfan-ocr.py \
    +    INPUT_DATASET OUTPUT_DATASET
  • baidu/Unlimited-OCRready · a10g-small

    unlimited-ocr-vllm.py ready to run · a10g-small

    Convert document images to markdown using Baidu Unlimited-OCR with vLLM.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr-vllm.py \
    +    INPUT_DATASET OUTPUT_DATASET
  • baidu/Unlimited-OCR-2ready · rtx-pro-6000

    unlimited-ocr2.py ready to run · rtx-pro-6000

    OCR whole documents (book volumes, folders of scans) with Baidu Unlimited-OCR-2.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr2.py \
    +    INPUT OUTPUT
    2 more recipes

    unlimited-ocr2-live.py ready to run, experimental · rtx-pro-6000

    unlimited-ocr2.py with a live view you can watch (and screen-record) while the Job runs.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr2-live.py \
    +    INPUT OUTPUT

    unlimited-ocr2-saturate.py ready to run, experimental · rtx-pro-6000

    OCR whole documents (book volumes, PDFs) with Baidu Unlimited-OCR-2 via saturate.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr2-saturate.py \
    +    INPUT OUTPUT
  • datalab-to/liftready · a100-large

    lift-extract.py ready to run · a100-large

    Extract structured JSON from document images OR multi-page PDFs using Datalab's lift model (datalab-to/lift, 9B, Qwen3.5-based).

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lift-extract.py \
    +    INPUT_DATASET OUTPUT_DATASET --schema SCHEMA
  • datalab-to/surya-ocr-2ready · a10g-small

    surya-ocr.py ready to run · a10g-small

    Document intelligence on images OR multi-page PDFs with Datalab's Surya OCR 2 (datalab-to/surya-ocr-2, 650M, Qwen3.5-style).

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/surya-ocr.py \
    +    INPUT_DATASET OUTPUT_DATASET
  • deepseek-ai/DeepSeek-OCRready · a10g-small

    deepseek-ocr-vllm.py ready to run · a10g-small

    Convert document images to markdown using DeepSeek-OCR with vLLM.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/deepseek-ocr-vllm.py \
    +    INPUT_DATASET OUTPUT_DATASET
  • deepseek-ai/DeepSeek-OCR-2ready · a10g-small

    deepseek-ocr2-vllm.py ready to run · a10g-small

    Convert document images to markdown using DeepSeek-OCR-2 with vLLM.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/deepseek-ocr2-vllm.py \
    +    INPUT_DATASET OUTPUT_DATASET
  • lightonai/LightOnOCR-2-1Bready · a10g-small

    lighton-ocr2.py ready to run · a10g-small

    Convert document images to markdown using LightOnOCR-2 with vLLM.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr2.py \
    +    INPUT_DATASET OUTPUT_DATASET
    1 more recipe

    lighton-ocr2-saturate.py ready to run · a10g-small

    Convert document images to markdown using LightOnOCR-2 via saturate.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr2-saturate.py \
    +    INPUT_DATASET OUTPUT_DATASET
  • lightonai/LightOnOCR-3-4Bready · a10g-small

    lighton-ocr3-bucket.py ready to run · a10g-small

    OCR images and PDFs from an HF Bucket (or a directory) using LightOnOCR-3, writing markdown files.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr3-bucket.py \
    +    INPUT OUTPUT
    1 more recipe

    lighton-ocr3.py ready to run · a10g-small

    Convert document images to markdown (or layout blocks) using LightOnOCR-3 with vLLM.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr3.py \
    +    INPUT_DATASET OUTPUT_DATASET
  • numind/NuExtract3ready · a10g-small

    nuextract3.py ready to run · a10g-small

    Convert document images to markdown OR extract structured JSON using NuExtract3 with vLLM.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/nuextract3.py \
    +    INPUT_DATASET OUTPUT_DATASET
  • openbmb/MiniCPM-OCR-1.0ready · a10g-large

    minicpm-ocr.py ready to run, experimental · a10g-large

    Convert document images to markdown with OpenBMB's MiniCPM-OCR 1.0 pipeline.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/minicpm-ocr.py \
    +    INPUT OUTPUT
  • PaddlePaddle/PaddleOCR-VL-1.6ready · a10g-small

    paddleocr-vl-1.6.py ready to run · a10g-small

    Convert document images to text/tables/formulas using PaddleOCR-VL-1.6 with vLLM.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/paddleocr-vl-1.6.py \
    +    INPUT_DATASET OUTPUT_DATASET
  • rednote-hilab/dots.mocrready · a10g-small

    dots-mocr.py ready to run · a10g-small

    Convert document images to markdown using dots.mocr with vLLM.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/dots-mocr.py \
    +    INPUT_DATASET OUTPUT_DATASET
  • rednote-hilab/dots.ocrready · a10g-small

    dots-ocr.py ready to run · a10g-small

    Convert document images to markdown using DoTS.ocr with vLLM.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/dots-ocr.py \
    +    INPUT_DATASET OUTPUT_DATASET
  • tencent/HunyuanOCRready · a10g-small

    hunyuan-ocr-1.5.py ready to run · a10g-small

    Convert document images to markdown using HunyuanOCR-1.5 with vLLM.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/hunyuan-ocr-1.5.py \
    +    INPUT_DATASET OUTPUT_DATASET
  • zai-org/GLM-OCRready · a10g-small

    glm-ocr.py ready to run · a10g-small

    Convert document images to markdown using GLM-OCR with vLLM.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/glm-ocr.py \
    +    INPUT_DATASET OUTPUT_DATASET

Transcription

  • CohereLabs/cohere-transcribe-03-2026options needed

    cohere-transcribe-vllm.py set options first

    Transcribe audio files from a directory using Cohere Transcribe via vLLM.

    Read the script for its options. It has no launch settings yet.

    2 more recipes

    cohere-transcribe.py set options first

    Transcribe audio files from a directory using Cohere Transcribe via transformers.

    Read the script for its options. It has no launch settings yet.

    easytranscriber-transcribe.py set options first

    Transcribe audio with word-level timestamps using kb-labb/easytranscriber.

    Read the script for its options. It has no launch settings yet.

  • distil-whisper/distil-large-v3.5options needed

    easytranscriber-transcribe.py set options first

    Transcribe audio with word-level timestamps using kb-labb/easytranscriber.

    Read the script for its options. It has no launch settings yet.

  • facebook/mms-1b-alloptions needed

    easytranscriber-transcribe.py set options first

    Transcribe audio with word-level timestamps using kb-labb/easytranscriber.

    Read the script for its options. It has no launch settings yet.

  • ibm-granite/granite-speech-5.0-470m-turboctcoptions needed

    granite-turboctc-transcribe.py set options first

    Transcribe English audio files with IBM Granite Speech 5.0 TurboCTC (470M).

    Read the script for its options. It has no launch settings yet.

  • nvidia/NVIDIA-Nemotron-3.5-Transcribe-30B-A4Bready · rtx-pro-6000

    nemotron-transcribe.py ready to run · rtx-pro-6000

    Transcribe audio with NVIDIA Nemotron 3.5 Transcribe via an in-job vLLM server.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/transcription/raw/main/nemotron-transcribe.py \
    +    INPUT_DIR OUTPUT_DIR
  • OpenMOSS-Team/MOSS-Transcribe-Diarizeoptions needed

    moss-transcribe-diarize.py set options first

    Transcribe + diarize audio files using MOSS-Transcribe-Diarize (0.9B).

    Read the script for its options. It has no launch settings yet.

    1 more recipe

    moss-transcribe-diarize-server.py set options first

    High-throughput transcription + diarization via an in-job sgl-omni server.

    Read the script for its options. It has no launch settings yet.

Segmentation

  • facebook/sam3example

    detect-objects.py example from the script

    Detect objects in images using Meta's SAM3 (Segment Anything Model 3).

    hf jobs uv run --flavor a100-large \
    +    -s HF_TOKEN \
    +    https://huggingface.co/datasets/uv-scripts/sam3/raw/main/detect-objects.py \
    +    input-dataset output-dataset \
    +    --class-name photograph \
    +    --confidence-threshold 0.5
    1 more recipe

    segment-objects.py example from the script

    Segment objects in images using Meta's SAM3 (Segment Anything Model 3).

    hf jobs uv run --flavor a100-large \
    +    -s HF_TOKEN \
    +    https://huggingface.co/datasets/uv-scripts/sam3/raw/main/segment-objects.py \
    +    input-dataset output-dataset \
    +    --class-name photograph

Object detection

  • Qwen/Qwen3.6-35B-A3Bready · a100-large

    qwen3vl-detect.py ready to run · a100-large

    Instruction-oriented object detection with Qwen3-VL via vLLM.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/vlm-object-detection/raw/main/qwen3vl-detect.py \
    +    INPUT_DATASET OUTPUT_DATASET
    1 more recipe

    qwen3vl-detect-fewshot.py ready to run · a100-large

    [FEW-SHOT VARIANT] Instruction-oriented object detection with Qwen3-VL via vLLM.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/vlm-object-detection/raw/main/qwen3vl-detect-fewshot.py \
    +    INPUT_DATASET OUTPUT_DATASET

Video

  • NemoStation/Marlin-2Bready · a10g-small

    marlin-caption.py ready to run · a10g-small

    Caption videos with timestamped events using Marlin-2B, writing a resumable dataset.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/video/raw/main/marlin-caption.py \
    +    INPUT_DIR OUTPUT
  • Qwen/Qwen3.8-27Bready · a100-large

    qwen38-caption.py ready to run · a100-large

    Caption whole videos — no chunking — with Qwen3.8-27B, writing a resumable dataset.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/video/raw/main/qwen38-caption.py \
    +    INPUT_DIR OUTPUT

Classification

  • fastino/gliner2.5-multi-v1ready · t4-small

    classify-gliner2.py ready to run · t4-small

    Classify a text column of a Hub dataset with GLiNER2 — zero-shot, or with your fine-tuned model.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/classification/raw/main/classify-gliner2.py \
    +    INPUT_DATASET OUTPUT_DATASET
  • HuggingFaceTB/SmolLM3-3Bready · l4x1

    classify-dataset-sglang.py ready to run · l4x1

    Classify text columns in Hugging Face datasets using SGLang with reasoning-aware models.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/classification/raw/main/classify-dataset-sglang.py \
    +    --input-dataset INPUT_DATASET --column COLUMN --labels LABELS --output-dataset OUTPUT_DATASET
    1 more recipe

    classify-dataset.py ready to run · l4x1

    Classify text columns in Hugging Face datasets using vLLM with structured outputs.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/classification/raw/main/classify-dataset.py \
    +    --input-dataset INPUT_DATASET --column COLUMN --labels LABELS --output-dataset OUTPUT_DATASET

Embeddings

  • BAAI/bge-base-en-v1.5example

    embed-to-lance.py example from the script

    Embed a Hugging Face dataset and push it back as a Lance vector index — a Hub dataset that IS a searchable vector database.

    hf jobs uv run --flavor l4x1 -s HF_TOKEN https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/embed-to-lance.py \
    +    stanfordnlp/imdb your-name/imdb-vecdb --column text --model BAAI/bge-base-en-v1.5 --private
  • Qwen/Qwen3-Embedding-0.6Bexample

    generate-embeddings-vllm.py example from the script

    High-throughput embedding generation with vLLM pooling mode — the "scale" variant of generate-embeddings.py, for large *decoder* embedding models (e.g

    hf jobs uv run --flavor l4x1 -s HF_TOKEN https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/generate-embeddings-vllm.py \
    +    stanfordnlp/imdb your-name/imdb-embeddings --column text --model Qwen/Qwen3-Embedding-0.6B --private
  • sentence-transformers/all-MiniLM-L6-v2example

    generate-embeddings.py example from the script

    Generate embeddings for a Hugging Face dataset (text OR images) with sentence-transformers, and push the result back to the Hub as a new dataset with

    hf jobs uv run --flavor l4x1 -s HF_TOKEN https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/generate-embeddings.py \
    +    stanfordnlp/imdb  your-name/imdb-embeddings \
    +    --column text --model sentence-transformers/all-MiniLM-L6-v2
    1 more recipe

    launch-embedding-fleet.py set options first

    Fan one embedding run out across N Hugging Face Jobs, then consolidate.

    Read the script for its options. It has no launch settings yet.

Text generation

  • Qwen/Qwen2-VL-7B-Instructready · l40sx1

    vlm-classify.py ready to run · l40sx1

    Classify images using Vision Language Models with vLLM.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/vllm/raw/main/vlm-classify.py \
    +    INPUT_DATASET OUTPUT_DATASET --classes CLASSES
  • Qwen/Qwen3-30B-A3B-Instruct-2507ready · a100-large

    generate-responses.py ready to run · a100-large

    Generate responses for prompts in a dataset using vLLM for efficient GPU inference.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/vllm/raw/main/generate-responses.py \
    +    SRC_DATASET_HUB_ID OUTPUT_DATASET_HUB_ID

Fine-tuning

  • fastino/gliner2.5-multi-v1ready · t4-small

    train-gliner2.py ready to run · t4-small

    Fine-tune GLiNER2 into a text classifier — a small model (74M to 287M parameters, depending on the base checkpoint) that already works zero-shot.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-gliner2.py \
    +    INPUT_DATASET OUTPUT_REPO
  • LiquidAI/LFM2.5-Encoder-350Mready · l4x1

    train-classifier.py ready to run · l4x1

    Fine-tune a text-classification encoder on a Hub dataset and push the trained model to the Hub.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-classifier.py \
    +    INPUT_DATASET OUTPUT_REPO
  • sentence-transformers/all-MiniLM-L6-v2example

    train-setfit.py example from the script

    Few-shot text classification with SetFit — train on 8-64 labelled examples per class, on CPU or GPU.

    hf jobs uv run --flavor cpu-basic --secrets HF_TOKEN \
    +    https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-setfit.py \
    +    fancyzhx/ag_news username/ag-news-setfit \
    +    --num-samples 8
+ +
+ + + diff --git a/run-on-jobs/recipes.json b/run-on-jobs/recipes.json new file mode 100644 index 0000000..144b42d --- /dev/null +++ b/run-on-jobs/recipes.json @@ -0,0 +1,796 @@ +{ + "recipes": [ + { + "kind": "run", + "task": "Classification", + "script": "classification/classify-dataset-sglang.py", + "url": "https://huggingface.co/datasets/uv-scripts/classification/raw/main/classify-dataset-sglang.py", + "models": [ + "HuggingFaceTB/SmolLM3-3B" + ], + "support": null, + "source": "header", + "flavor": "l4x1", + "timeout": "1h", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/classification/raw/main/classify-dataset-sglang.py \\\n --input-dataset INPUT_DATASET --column COLUMN --labels LABELS --output-dataset OUTPUT_DATASET", + "summary": "Classify text columns in Hugging Face datasets using SGLang with reasoning-aware models.", + "declared": true + }, + { + "kind": "run", + "task": "Classification", + "script": "classification/classify-dataset.py", + "url": "https://huggingface.co/datasets/uv-scripts/classification/raw/main/classify-dataset.py", + "models": [ + "HuggingFaceTB/SmolLM3-3B" + ], + "support": null, + "source": "header", + "flavor": "l4x1", + "timeout": "1h", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/classification/raw/main/classify-dataset.py \\\n --input-dataset INPUT_DATASET --column COLUMN --labels LABELS --output-dataset OUTPUT_DATASET", + "summary": "Classify text columns in Hugging Face datasets using vLLM with structured outputs.", + "declared": true + }, + { + "kind": "run", + "task": "Classification", + "script": "classification/classify-gliner2.py", + "url": "https://huggingface.co/datasets/uv-scripts/classification/raw/main/classify-gliner2.py", + "models": [ + "fastino/gliner2.5-multi-v1" + ], + "support": null, + "source": "header", + "flavor": "t4-small", + "timeout": "1h", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/classification/raw/main/classify-gliner2.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "Classify a text column of a Hub dataset with GLiNER2 — zero-shot, or with your fine-tuned model.", + "declared": true + }, + { + "kind": "train", + "task": "Fine-tuning", + "script": "classification/train-classifier.py", + "url": "https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-classifier.py", + "models": [ + "LiquidAI/LFM2.5-Encoder-350M" + ], + "support": null, + "source": "header", + "flavor": "l4x1", + "timeout": "1h", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-classifier.py \\\n INPUT_DATASET OUTPUT_REPO", + "summary": "Fine-tune a text-classification encoder on a Hub dataset and push the trained model to the Hub.", + "declared": false + }, + { + "kind": "train", + "task": "Fine-tuning", + "script": "classification/train-gliner2.py", + "url": "https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-gliner2.py", + "models": [ + "fastino/gliner2.5-multi-v1" + ], + "support": null, + "source": "header", + "flavor": "t4-small", + "timeout": "1h", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-gliner2.py \\\n INPUT_DATASET OUTPUT_REPO", + "summary": "Fine-tune GLiNER2 into a text classifier — a small model (74M to 287M parameters, depending on the base checkpoint) that already works zero-shot.", + "declared": false + }, + { + "kind": "train", + "task": "Fine-tuning", + "script": "classification/train-setfit.py", + "url": "https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-setfit.py", + "models": [ + "sentence-transformers/all-MiniLM-L6-v2" + ], + "support": null, + "source": "documented", + "flavor": null, + "timeout": null, + "command": "hf jobs uv run --flavor cpu-basic --secrets HF_TOKEN \\\n https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-setfit.py \\\n fancyzhx/ag_news username/ag-news-setfit \\\n --num-samples 8", + "summary": "Few-shot text classification with SetFit — train on 8-64 labelled examples per class, on CPU or GPU.", + "declared": false + }, + { + "kind": "run", + "task": "Embeddings", + "script": "embeddings/embed-to-lance.py", + "url": "https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/embed-to-lance.py", + "models": [ + "BAAI/bge-base-en-v1.5" + ], + "support": null, + "source": "documented", + "flavor": null, + "timeout": null, + "command": "hf jobs uv run --flavor l4x1 -s HF_TOKEN https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/embed-to-lance.py \\\n stanfordnlp/imdb your-name/imdb-vecdb --column text --model BAAI/bge-base-en-v1.5 --private", + "summary": "Embed a Hugging Face dataset and push it back as a Lance vector index — a Hub dataset that IS a searchable vector database.", + "declared": false + }, + { + "kind": "run", + "task": "Embeddings", + "script": "embeddings/generate-embeddings-vllm.py", + "url": "https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/generate-embeddings-vllm.py", + "models": [ + "Qwen/Qwen3-Embedding-0.6B" + ], + "support": null, + "source": "documented", + "flavor": null, + "timeout": null, + "command": "hf jobs uv run --flavor l4x1 -s HF_TOKEN https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/generate-embeddings-vllm.py \\\n stanfordnlp/imdb your-name/imdb-embeddings --column text --model Qwen/Qwen3-Embedding-0.6B --private", + "summary": "High-throughput embedding generation with vLLM pooling mode — the \"scale\" variant of generate-embeddings.py, for large *decoder* embedding models (e.g", + "declared": false + }, + { + "kind": "run", + "task": "Embeddings", + "script": "embeddings/generate-embeddings.py", + "url": "https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/generate-embeddings.py", + "models": [ + "sentence-transformers/all-MiniLM-L6-v2" + ], + "support": null, + "source": "documented", + "flavor": null, + "timeout": null, + "command": "hf jobs uv run --flavor l4x1 -s HF_TOKEN https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/generate-embeddings.py \\\n stanfordnlp/imdb your-name/imdb-embeddings \\\n --column text --model sentence-transformers/all-MiniLM-L6-v2", + "summary": "Generate embeddings for a Hugging Face dataset (text OR images) with sentence-transformers, and push the result back to the Hub as a new dataset with ", + "declared": true + }, + { + "kind": "run", + "task": "Embeddings", + "script": "embeddings/launch-embedding-fleet.py", + "url": "https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/launch-embedding-fleet.py", + "models": [ + "sentence-transformers/all-MiniLM-L6-v2" + ], + "support": null, + "source": "flags-needed", + "flavor": null, + "timeout": null, + "command": null, + "summary": "Fan one embedding run out across N Hugging Face Jobs, then consolidate.", + "declared": false + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/deepseek-ocr-vllm.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/deepseek-ocr-vllm.py", + "models": [ + "deepseek-ai/DeepSeek-OCR" + ], + "support": "core", + "source": "header", + "flavor": "a10g-small", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/deepseek-ocr-vllm.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "Convert document images to markdown using DeepSeek-OCR with vLLM.", + "declared": true + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/deepseek-ocr2-vllm.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/deepseek-ocr2-vllm.py", + "models": [ + "deepseek-ai/DeepSeek-OCR-2" + ], + "support": "core", + "source": "header", + "flavor": "a10g-small", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/deepseek-ocr2-vllm.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "Convert document images to markdown using DeepSeek-OCR-2 with vLLM.", + "declared": true + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/dots-mocr.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/dots-mocr.py", + "models": [ + "rednote-hilab/dots.mocr" + ], + "support": "core", + "source": "header", + "flavor": "a10g-small", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/dots-mocr.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "Convert document images to markdown using dots.mocr with vLLM.", + "declared": true + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/dots-ocr.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/dots-ocr.py", + "models": [ + "rednote-hilab/dots.ocr" + ], + "support": "core", + "source": "header", + "flavor": "a10g-small", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/dots-ocr.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "Convert document images to markdown using DoTS.ocr with vLLM.", + "declared": true + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/glm-ocr.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/glm-ocr.py", + "models": [ + "zai-org/GLM-OCR" + ], + "support": "core", + "source": "header", + "flavor": "a10g-small", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/glm-ocr.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "Convert document images to markdown using GLM-OCR with vLLM.", + "declared": true + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/hunyuan-ocr-1.5.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/hunyuan-ocr-1.5.py", + "models": [ + "tencent/HunyuanOCR" + ], + "support": "core", + "source": "header", + "flavor": "a10g-small", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/hunyuan-ocr-1.5.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "Convert document images to markdown using HunyuanOCR-1.5 with vLLM.", + "declared": true + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/lift-extract.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lift-extract.py", + "models": [ + "datalab-to/lift" + ], + "support": "core", + "source": "header", + "flavor": "a100-large", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lift-extract.py \\\n INPUT_DATASET OUTPUT_DATASET --schema SCHEMA", + "summary": "Extract structured JSON from document images OR multi-page PDFs using Datalab's lift model (datalab-to/lift, 9B, Qwen3.5-based).", + "declared": true + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/lighton-ocr2-saturate.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr2-saturate.py", + "models": [ + "lightonai/LightOnOCR-2-1B" + ], + "support": "core", + "source": "header", + "flavor": "a10g-small", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr2-saturate.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "Convert document images to markdown using LightOnOCR-2 via saturate.", + "declared": true + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/lighton-ocr2.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr2.py", + "models": [ + "lightonai/LightOnOCR-2-1B" + ], + "support": "core", + "source": "header", + "flavor": "a10g-small", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr2.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "Convert document images to markdown using LightOnOCR-2 with vLLM.", + "declared": true + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/lighton-ocr3-bucket.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr3-bucket.py", + "models": [ + "lightonai/LightOnOCR-3-4B" + ], + "support": "core", + "source": "header", + "flavor": "a10g-small", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr3-bucket.py \\\n INPUT OUTPUT", + "summary": "OCR images and PDFs from an HF Bucket (or a directory) using LightOnOCR-3, writing markdown files.", + "declared": true + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/lighton-ocr3.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr3.py", + "models": [ + "lightonai/LightOnOCR-3-4B" + ], + "support": "core", + "source": "header", + "flavor": "a10g-small", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr3.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "Convert document images to markdown (or layout blocks) using LightOnOCR-3 with vLLM.", + "declared": true + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/minicpm-ocr.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/minicpm-ocr.py", + "models": [ + "openbmb/MiniCPM-OCR-1.0" + ], + "support": "experimental", + "source": "header", + "flavor": "a10g-large", + "timeout": "2h", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/minicpm-ocr.py \\\n INPUT OUTPUT", + "summary": "Convert document images to markdown with OpenBMB's MiniCPM-OCR 1.0 pipeline.", + "declared": false + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/nuextract3.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/nuextract3.py", + "models": [ + "numind/NuExtract3" + ], + "support": "core", + "source": "header", + "flavor": "a10g-small", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/nuextract3.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "Convert document images to markdown OR extract structured JSON using NuExtract3 with vLLM.", + "declared": true + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/olmocr2-vllm.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/olmocr2-vllm.py", + "models": [ + "allenai/olmOCR-2-7B-1025-FP8" + ], + "support": "core", + "source": "header", + "flavor": "a10g-small", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/olmocr2-vllm.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "Convert document images to markdown using olmOCR-2 with vLLM.", + "declared": true + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/ovis-ocr2-saturate.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/ovis-ocr2-saturate.py", + "models": [ + "ATH-MaaS/OvisOCR2" + ], + "support": "core", + "source": "header", + "flavor": "a10g-small", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/ovis-ocr2-saturate.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "Convert document images to markdown using OvisOCR2 via saturate.", + "declared": true + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/ovis-ocr2.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/ovis-ocr2.py", + "models": [ + "ATH-MaaS/OvisOCR2" + ], + "support": "core", + "source": "header", + "flavor": "a10g-small", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/ovis-ocr2.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "Convert document images to markdown using OvisOCR2 with vLLM.", + "declared": true + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/paddleocr-vl-1.6.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/paddleocr-vl-1.6.py", + "models": [ + "PaddlePaddle/PaddleOCR-VL-1.6" + ], + "support": "core", + "source": "header", + "flavor": "a10g-small", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/paddleocr-vl-1.6.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "Convert document images to text/tables/formulas using PaddleOCR-VL-1.6 with vLLM.", + "declared": true + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/qianfan-ocr.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/qianfan-ocr.py", + "models": [ + "baidu/Qianfan-OCR" + ], + "support": "core", + "source": "header", + "flavor": "a10g-small", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/qianfan-ocr.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "Convert document images to markdown using Qianfan-OCR with vLLM.", + "declared": true + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/surya-ocr.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/surya-ocr.py", + "models": [ + "datalab-to/surya-ocr-2" + ], + "support": "core", + "source": "header", + "flavor": "a10g-small", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/surya-ocr.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "Document intelligence on images OR multi-page PDFs with Datalab's Surya OCR 2 (datalab-to/surya-ocr-2, 650M, Qwen3.5-style).", + "declared": true + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/unlimited-ocr-vllm.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr-vllm.py", + "models": [ + "baidu/Unlimited-OCR" + ], + "support": "core", + "source": "header", + "flavor": "a10g-small", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr-vllm.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "Convert document images to markdown using Baidu Unlimited-OCR with vLLM.", + "declared": true + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/unlimited-ocr2-live.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr2-live.py", + "models": [ + "baidu/Unlimited-OCR-2" + ], + "support": "experimental", + "source": "header", + "flavor": "rtx-pro-6000", + "timeout": "4h", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr2-live.py \\\n INPUT OUTPUT", + "summary": "unlimited-ocr2.py with a live view you can watch (and screen-record) while the Job runs.", + "declared": false + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/unlimited-ocr2-saturate.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr2-saturate.py", + "models": [ + "baidu/Unlimited-OCR-2" + ], + "support": "experimental", + "source": "header", + "flavor": "rtx-pro-6000", + "timeout": "4h", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr2-saturate.py \\\n INPUT OUTPUT", + "summary": "OCR whole documents (book volumes, PDFs) with Baidu Unlimited-OCR-2 via saturate.", + "declared": false + }, + { + "kind": "run", + "task": "OCR", + "script": "ocr/unlimited-ocr2.py", + "url": "https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr2.py", + "models": [ + "baidu/Unlimited-OCR-2" + ], + "support": "core", + "source": "header", + "flavor": "rtx-pro-6000", + "timeout": "4h", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr2.py \\\n INPUT OUTPUT", + "summary": "OCR whole documents (book volumes, folders of scans) with Baidu Unlimited-OCR-2.", + "declared": true + }, + { + "kind": "run", + "task": "Segmentation", + "script": "sam3/detect-objects.py", + "url": "https://huggingface.co/datasets/uv-scripts/sam3/raw/main/detect-objects.py", + "models": [ + "facebook/sam3" + ], + "support": null, + "source": "documented", + "flavor": null, + "timeout": null, + "command": "hf jobs uv run --flavor a100-large \\\n -s HF_TOKEN \\\n https://huggingface.co/datasets/uv-scripts/sam3/raw/main/detect-objects.py \\\n input-dataset output-dataset \\\n --class-name photograph \\\n --confidence-threshold 0.5", + "summary": "Detect objects in images using Meta's SAM3 (Segment Anything Model 3).", + "declared": true + }, + { + "kind": "run", + "task": "Segmentation", + "script": "sam3/segment-objects.py", + "url": "https://huggingface.co/datasets/uv-scripts/sam3/raw/main/segment-objects.py", + "models": [ + "facebook/sam3" + ], + "support": null, + "source": "documented", + "flavor": null, + "timeout": null, + "command": "hf jobs uv run --flavor a100-large \\\n -s HF_TOKEN \\\n https://huggingface.co/datasets/uv-scripts/sam3/raw/main/segment-objects.py \\\n input-dataset output-dataset \\\n --class-name photograph", + "summary": "Segment objects in images using Meta's SAM3 (Segment Anything Model 3).", + "declared": true + }, + { + "kind": "run", + "task": "Transcription", + "script": "transcription/cohere-transcribe-vllm.py", + "url": "https://huggingface.co/datasets/uv-scripts/transcription/raw/main/cohere-transcribe-vllm.py", + "models": [ + "CohereLabs/cohere-transcribe-03-2026" + ], + "support": null, + "source": "flags-needed", + "flavor": null, + "timeout": null, + "command": null, + "summary": "Transcribe audio files from a directory using Cohere Transcribe via vLLM.", + "declared": false + }, + { + "kind": "run", + "task": "Transcription", + "script": "transcription/cohere-transcribe.py", + "url": "https://huggingface.co/datasets/uv-scripts/transcription/raw/main/cohere-transcribe.py", + "models": [ + "CohereLabs/cohere-transcribe-03-2026" + ], + "support": null, + "source": "flags-needed", + "flavor": null, + "timeout": null, + "command": null, + "summary": "Transcribe audio files from a directory using Cohere Transcribe via transformers.", + "declared": false + }, + { + "kind": "run", + "task": "Transcription", + "script": "transcription/easytranscriber-transcribe.py", + "url": "https://huggingface.co/datasets/uv-scripts/transcription/raw/main/easytranscriber-transcribe.py", + "models": [ + "CohereLabs/cohere-transcribe-03-2026", + "distil-whisper/distil-large-v3.5", + "facebook/mms-1b-all" + ], + "support": null, + "source": "flags-needed", + "flavor": null, + "timeout": null, + "command": null, + "summary": "Transcribe audio with word-level timestamps using kb-labb/easytranscriber.", + "declared": false + }, + { + "kind": "run", + "task": "Transcription", + "script": "transcription/granite-turboctc-transcribe.py", + "url": "https://huggingface.co/datasets/uv-scripts/transcription/raw/main/granite-turboctc-transcribe.py", + "models": [ + "ibm-granite/granite-speech-5.0-470m-turboctc" + ], + "support": null, + "source": "flags-needed", + "flavor": null, + "timeout": null, + "command": null, + "summary": "Transcribe English audio files with IBM Granite Speech 5.0 TurboCTC (470M).", + "declared": false + }, + { + "kind": "run", + "task": "Transcription", + "script": "transcription/moss-transcribe-diarize-server.py", + "url": "https://huggingface.co/datasets/uv-scripts/transcription/raw/main/moss-transcribe-diarize-server.py", + "models": [ + "OpenMOSS-Team/MOSS-Transcribe-Diarize" + ], + "support": null, + "source": "flags-needed", + "flavor": null, + "timeout": null, + "command": null, + "summary": "High-throughput transcription + diarization via an in-job sgl-omni server.", + "declared": false + }, + { + "kind": "run", + "task": "Transcription", + "script": "transcription/moss-transcribe-diarize.py", + "url": "https://huggingface.co/datasets/uv-scripts/transcription/raw/main/moss-transcribe-diarize.py", + "models": [ + "OpenMOSS-Team/MOSS-Transcribe-Diarize" + ], + "support": null, + "source": "flags-needed", + "flavor": null, + "timeout": null, + "command": null, + "summary": "Transcribe + diarize audio files using MOSS-Transcribe-Diarize (0.9B).", + "declared": false + }, + { + "kind": "run", + "task": "Transcription", + "script": "transcription/nemotron-transcribe.py", + "url": "https://huggingface.co/datasets/uv-scripts/transcription/raw/main/nemotron-transcribe.py", + "models": [ + "nvidia/NVIDIA-Nemotron-3.5-Transcribe-30B-A4B" + ], + "support": null, + "source": "header", + "flavor": "rtx-pro-6000", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/transcription/raw/main/nemotron-transcribe.py \\\n INPUT_DIR OUTPUT_DIR", + "summary": "Transcribe audio with NVIDIA Nemotron 3.5 Transcribe via an in-job vLLM server.", + "declared": true + }, + { + "kind": "run", + "task": "Video", + "script": "video/marlin-caption.py", + "url": "https://huggingface.co/datasets/uv-scripts/video/raw/main/marlin-caption.py", + "models": [ + "NemoStation/Marlin-2B" + ], + "support": null, + "source": "header", + "flavor": "a10g-small", + "timeout": "2h", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/video/raw/main/marlin-caption.py \\\n INPUT_DIR OUTPUT", + "summary": "Caption videos with timestamped events using Marlin-2B, writing a resumable dataset.", + "declared": true + }, + { + "kind": "run", + "task": "Video", + "script": "video/qwen38-caption.py", + "url": "https://huggingface.co/datasets/uv-scripts/video/raw/main/qwen38-caption.py", + "models": [ + "Qwen/Qwen3.8-27B" + ], + "support": null, + "source": "header", + "flavor": "a100-large", + "timeout": null, + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/video/raw/main/qwen38-caption.py \\\n INPUT_DIR OUTPUT", + "summary": "Caption whole videos — no chunking — with Qwen3.8-27B, writing a resumable dataset.", + "declared": true + }, + { + "kind": "run", + "task": "Text generation", + "script": "vllm/generate-responses.py", + "url": "https://huggingface.co/datasets/uv-scripts/vllm/raw/main/generate-responses.py", + "models": [ + "Qwen/Qwen3-30B-A3B-Instruct-2507" + ], + "support": null, + "source": "header", + "flavor": "a100-large", + "timeout": "2h", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/vllm/raw/main/generate-responses.py \\\n SRC_DATASET_HUB_ID OUTPUT_DATASET_HUB_ID", + "summary": "Generate responses for prompts in a dataset using vLLM for efficient GPU inference.", + "declared": false + }, + { + "kind": "run", + "task": "Text generation", + "script": "vllm/vlm-classify.py", + "url": "https://huggingface.co/datasets/uv-scripts/vllm/raw/main/vlm-classify.py", + "models": [ + "Qwen/Qwen2-VL-7B-Instruct" + ], + "support": null, + "source": "header", + "flavor": "l40sx1", + "timeout": "1h", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/vllm/raw/main/vlm-classify.py \\\n INPUT_DATASET OUTPUT_DATASET --classes CLASSES", + "summary": "Classify images using Vision Language Models with vLLM.", + "declared": true + }, + { + "kind": "run", + "task": "Object detection", + "script": "vlm-object-detection/qwen3vl-detect-fewshot.py", + "url": "https://huggingface.co/datasets/uv-scripts/vlm-object-detection/raw/main/qwen3vl-detect-fewshot.py", + "models": [ + "Qwen/Qwen3.6-35B-A3B" + ], + "support": null, + "source": "header", + "flavor": "a100-large", + "timeout": "1h", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/vlm-object-detection/raw/main/qwen3vl-detect-fewshot.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "[FEW-SHOT VARIANT] Instruction-oriented object detection with Qwen3-VL via vLLM.", + "declared": true + }, + { + "kind": "run", + "task": "Object detection", + "script": "vlm-object-detection/qwen3vl-detect.py", + "url": "https://huggingface.co/datasets/uv-scripts/vlm-object-detection/raw/main/qwen3vl-detect.py", + "models": [ + "Qwen/Qwen3.6-35B-A3B" + ], + "support": null, + "source": "header", + "flavor": "a100-large", + "timeout": "1h", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/vlm-object-detection/raw/main/qwen3vl-detect.py \\\n INPUT_DATASET OUTPUT_DATASET", + "summary": "Instruction-oriented object detection with Qwen3-VL via vLLM.", + "declared": true + } + ], + "data_tools": [ + { + "repo": "uv-scripts/object-detection", + "description": "Check and convert detection datasets" + }, + { + "repo": "uv-scripts/deduplication", + "description": "Remove near-duplicate text" + }, + { + "repo": "uv-scripts/build-atlas", + "description": "Build an embedding atlas" + }, + { + "repo": "uv-scripts/iiif-tiles", + "description": "Make IIIF deep-zoom tiles" + }, + { + "repo": "uv-scripts/data-processing", + "description": "Convert uploads to optimized Parquet" + } + ] +} diff --git a/tools/build-catalog.py b/tools/build-catalog.py new file mode 100644 index 0000000..e6318c8 --- /dev/null +++ b/tools/build-catalog.py @@ -0,0 +1,395 @@ +#!/usr/bin/env python3 +"""Generate the Run on Jobs Space from the recipes in this repo. + + python3 tools/build-catalog.py # write run-on-jobs/ + python3 tools/build-catalog.py --check # fail if run-on-jobs/ is stale + python3 tools/build-catalog.py --verify-models # also check each declared model on the Hub + +Scripts are only parsed, never imported or run. Standard library only. +""" + +import argparse +import ast +import html +import json +import re +import sys +import tomllib +import urllib.error +import urllib.request +from pathlib import Path + +ROOT = Path(__file__).resolve().parent.parent +OUTPUT_DIR = ROOT / "run-on-jobs" +HUB_BASE = "https://huggingface.co/datasets/uv-scripts" + +TASKS = { + "ocr": "OCR", + "transcription": "Transcription", + "sam3": "Segmentation", + "vlm-object-detection": "Object detection", + "video": "Video", + "classification": "Classification", + "gliner": "Entities", + "embeddings": "Embeddings", + "vllm": "Text generation", +} +TRAINING_TASK = "Fine-tuning" +TASK_ORDER = [*TASKS.values(), TRAINING_TASK] + +DATA_TOOLS = { + "object-detection": "Check and convert detection datasets", + "deduplication": "Remove near-duplicate text", + "build-atlas": "Build an embedding atlas", + "iiif-tiles": "Make IIIF deep-zoom tiles", + "data-processing": "Convert uploads to optimized Parquet", +} + +# Recipes without a [tool.hf-jobs] header whose documented command passed a smoke Job with checked output. +# Only these and header recipes are declared on model pages. +SMOKE_TESTED_EXAMPLES = { + "embeddings/generate-embeddings.py", + "sam3/detect-objects.py", + "sam3/segment-objects.py", +} + +# Left out of the Space until they run again. +BROKEN = { + "gliner/extract-entities.py", # the default model's tokenizer needs tiktoken, which the script doesn't declare +} + +# Listed on the page, but not declared on model pages until the plain command works for the model. +NOT_DECLARED = { + "vllm/generate-responses.py", # the default model needs --max-model-len on the header's a100-large +} + +# Recipe metadata that names a family rather than a Hub repo. +NOT_HUB_MODELS = {"PaddlePaddle/PP-OCRv6"} + +OCR_SUPPORT_LEVELS = {"core", "experimental"} +SKIP_SCRIPT = re.compile(r"(^_|^test_|conftest|setup|benchmark|judge|compare)", re.IGNORECASE) +ALTERNATIVE_SCRIPT = re.compile(r"saturate|live|server|fleet|fewshot", re.IGNORECASE) +MODEL_ID = re.compile(r"^[A-Za-z0-9][\w.-]*/[\w.+-]+$") +PLACEHOLDER_OWNERS = {"org", "datasets", "models", "hf", "bucket", "buckets", "input", "output", "user", "your", "username", "path", "dir", "my-org", "uv-scripts"} + +STATUS = {"header": "ready to run", "documented": "example from the script", "flags-needed": "set options first"} +ROW_STATUS = {"header": "ready", "documented": "example", "flags-needed": "options needed"} + + +def read_header(text): + match = re.search(r"(?m)^# /// script\n((?:#.*\n)*?)# ///", text) + if not match: + return {} + lines = [line[2:] if line.startswith("# ") else line[1:] for line in match.group(1).splitlines()] + try: + return tomllib.loads("\n".join(lines)).get("tool", {}).get("hf-jobs", {}) + except tomllib.TOMLDecodeError: + return {} + + +def read_arguments(tree): + """Return module string constants and the add_argument calls, using only the syntax tree.""" + constants = {} + for node in tree.body: + if isinstance(node, ast.Assign) and len(node.targets) == 1 and isinstance(node.targets[0], ast.Name): + if isinstance(node.value, ast.Constant) and isinstance(node.value.value, str): + constants[node.targets[0].id] = node.value.value + + arguments = [] + for node in ast.walk(tree): + if not (isinstance(node, ast.Call) and isinstance(node.func, ast.Attribute) and node.func.attr == "add_argument"): + continue + names = [arg.value for arg in node.args if isinstance(arg, ast.Constant) and isinstance(arg.value, str)] + if not names: + continue + keywords = {keyword.arg: keyword.value for keyword in node.keywords if keyword.arg} + default = keywords.get("default") + if isinstance(default, ast.Constant): + default = default.value + elif isinstance(default, ast.Name): + default = constants.get(default.id) + else: + default = None + required = isinstance(keywords.get("required"), ast.Constant) and keywords["required"].value is True + arguments.append({"name": names[0], "default": default, "positional": not names[0].startswith("-"), "required": required}) + return constants, arguments + + +def find_models(constants, arguments): + candidates = [] + for argument in arguments: + if isinstance(argument["default"], str) and "model" in argument["name"].lower() and MODEL_ID.match(argument["default"]): + candidates.append(argument["default"]) + for name, value in constants.items(): + if "MODEL" in name.upper() and MODEL_ID.match(value): + candidates.append(value) + unique = dict.fromkeys(candidates) + return [model for model in unique if model.split("/")[0].lower() not in PLACEHOLDER_OWNERS] + + +def first_documented_command(text, script_name, url): + match = re.search(r"hf jobs uv run(?:[^\n]*\\\n)*[^\n]*", text) + if not match or script_name not in match.group(0): + return None + lines = [re.sub(r"^\s*(#\s*)?", "", line).rstrip(" \\") for line in match.group(0).split("\n")] + command = " \\\n ".join(line for line in lines if line) + if url not in command: + command = re.sub(r"(?
{html.escape(command)}
' + + +def recipe_html(recipe): + status = STATUS[recipe["source"]] + if recipe["support"] == "experimental": + status += ", experimental" + status_class = "warn" if recipe["source"] == "flags-needed" else "muted" + flavor = f" · {html.escape(recipe['flavor'])}" if recipe["flavor"] else "" + summary = f'

{html.escape(recipe["summary"])}

' if recipe["summary"] else "" + if recipe["source"] == "flags-needed": + body = f'

Read the script for its options. It has no launch settings yet.

' + else: + body = command_block(recipe["command"]) + name = recipe["script"].split("/")[-1] + return ( + f'

{html.escape(name)} ' + f'{status}{flavor}

{summary}{body}
' + ) + + +def model_row_html(task, model, recipes): + ranked = sorted(recipes, key=rank) + best = ranked[0] + row_status = ROW_STATUS[best["source"]] + (f" · {best['flavor']}" if best["flavor"] else "") + row_class = "warn" if best["source"] == "flags-needed" else "muted" + search_text = " ".join([model, task] + [f"{recipe['script']} {recipe['summary']}" for recipe in ranked]).lower() + others = ranked[1:] + more = "" + if others: + label = f"{len(others)} more recipe{'s' if len(others) > 1 else ''}" + more = f'
{label}' + "".join(recipe_html(recipe) for recipe in others) + "
" + return ( + f'
  • ' + f'{html.escape(model)}{html.escape(row_status)}' + + recipe_html(best) + more + "
  • " + ) + + +def render_index(recipes): + template = (ROOT / "tools" / "run-on-jobs-template.html").read_text() + entries = {} + for recipe in recipes: + for model in recipe["models"]: + entries.setdefault((recipe["task"], model), []).append(recipe) + + groups = [] + used_tasks = [] + for task in TASK_ORDER: + models = sorted((model for entry_task, model in entries if entry_task == task), key=str.lower) + if not models: + continue + used_tasks.append(task) + rows = "".join(model_row_html(task, model, entries[(task, model)]) for model in models) + groups.append(f'

    {html.escape(task)}

      {rows}
    ') + + filters = '' + "".join( + f'' for task in used_tasks + ) + tools = "".join( + f'
  • {html.escape(label)}
  • ' for folder, label in DATA_TOOLS.items() + ) + return template.replace("{{FILTERS}}", filters).replace("{{GROUPS}}", "".join(groups)).replace("{{TOOLS}}", tools) + + +def render_readme(recipes): + model_lines = "\n".join(f" - {model}" for model in declared_models(recipes)) + return f"""--- +title: Run on Jobs +emoji: ⚡ +colorFrom: blue +colorTo: gray +sdk: static +pinned: false +short_description: Run this model over your own data on HF Jobs +models: +{model_lines} +--- + +# Run on Jobs + +A catalogue of [uv-scripts](https://huggingface.co/uv-scripts) recipes: one command runs a model over your own data on [Hugging Face Jobs](https://huggingface.co/docs/hub/jobs). + +This Space is generated from [davanstrien/uv-scripts](https://github.com/davanstrien/uv-scripts). To change it, edit the recipes or `tools/build-catalog.py` there. Agents should read [AGENTS.md](./AGENTS.md). +""" + + +def render_agents(): + return """# Run a model on Hugging Face Jobs + +`recipes.json` lists one-command batch recipes. Find the model in `recipes[].models`. + + hf download uv-scripts/run-on-jobs recipes.json --repo-type space + +Each recipe has: + +- `kind`: `run` applies a model to data; `train` fine-tunes one. +- `command`: the command to start from. `INPUT` and `OUTPUT` are usually dataset IDs; read the script to confirm. +- `source`: how far to trust the command. + - `header`: the script carries its launch settings. + - `documented`: an example from the script's docs. It may set its own hardware flags. + - `flags-needed`: `command` is null. Read the script and choose the options yourself. + +Before you start a job: + +1. Read the options: open the recipe's `url`. +2. Preview without spending: `hf jobs uv run --dry-run `. Check the image and flavor; without a header a GPU recipe can resolve to `cpu-basic`. +3. Start small: pass `--max-samples` if the script has it. +4. Monitor: `hf jobs ps`, `hf jobs logs `. +5. Check the output. A completed job is not proof that its rows are correct. +""" + + +def generate(): + recipes = load_recipes() + catalog = { + "recipes": sorted(recipes, key=lambda recipe: recipe["script"]), + "data_tools": [{"repo": f"uv-scripts/{folder}", "description": label} for folder, label in DATA_TOOLS.items()], + } + return { + "index.html": render_index(recipes), + "README.md": render_readme(recipes), + "AGENTS.md": render_agents(), + "recipes.json": json.dumps(catalog, indent=1, ensure_ascii=False) + "\n", + } + + +def verify_models(recipes): + missing = [] + for model in declared_models(recipes): + try: + urllib.request.urlopen(f"https://huggingface.co/api/models/{model}", timeout=30) + except urllib.error.HTTPError as error: + missing.append(f"{model} (HTTP {error.code})") + return missing + + +def main(): + parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument("--check", action="store_true", help="Fail if run-on-jobs/ does not match the recipes") + parser.add_argument("--verify-models", action="store_true", help="Check that declared models exist on the Hub") + args = parser.parse_args() + + files = generate() + if args.check: + stale = [name for name, content in files.items() if not (OUTPUT_DIR / name).exists() or (OUTPUT_DIR / name).read_text() != content] + if stale: + print(f"Stale: {', '.join(stale)}. Run python3 tools/build-catalog.py and commit the result.") + return 1 + else: + for name, content in files.items(): + (OUTPUT_DIR / name).write_text(content) + + recipes = load_recipes() + print(f"{len(recipes)} recipes, {len(declared_models(recipes))} declared models") + if args.verify_models: + missing = verify_models(recipes) + if missing: + print("Declared models not found:", ", ".join(missing)) + return 1 + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/run-on-jobs-template.html b/tools/run-on-jobs-template.html new file mode 100644 index 0000000..cb74182 --- /dev/null +++ b/tools/run-on-jobs-template.html @@ -0,0 +1,290 @@ + + + + + +Run on Jobs + + + + + +
    +

    Run Hub models on your own data

    +

    One command starts a GPU on Hugging Face Jobs, runs the model over your whole dataset and saves the results to the Hub. There is nothing to clone.

    +
    +
    +

    Read seven scanned NASA pages with GLM-OCR and save the text to a new dataset on your account.

    hf jobs uv run \
    +    https://huggingface.co/datasets/uv-scripts/ocr/raw/main/glm-ocr.py \
    +    uv-scripts/ocr-demo your-username/ocr-demo-results
    The scan
    Scanned page listing Space Shuttle foods
    What the Job wrote
    Space Shuttle Food and Beverage List
    +
    +Foods*
    +
    +Applesauce (T)
    +Apricots, dried (IM)
    +Asparagus (R)
    +Bananas (FD)
    +Beef almondine (R)
    +Beef, corned (I) (T)
    +Beef and gravy (T)
    +Beef, ground w/pickle sauce (T)
    +Beef jerky (IM)
    +Beef patty (R)
    +Beef, slices w/barbeque sauce (T)
    +Beef steak (I) (T)
    +Beef stroganoff w/noodles (R)
    +Bread, seedless rye (I) (NF)
    +Broccoli au gratin (R)
    +Breakfast roll (I) (NF)
    +Candy, Life Savers*, assorted flavors (NF)
    +Cauliflower w/cheese (R)
    +Cereal, bran flakes (R)
    +Cereal, cornflakes (R)
    +Cereal, granola (R)
    +Cereal, granola w/blueberries (R)
    +Cereal, granola w/raisins (R)
    +Cheddar cheese spread (T)
    +Chicken a la king (T)
    +
    +Chicken and noodles (R)
    +Chicken and rice (R)
    +Chili mac w/beef (R)
    +Cookies, pecan (NF)
    +Cookies, shortbread (NF)
    +Crackers, graham (NF)
    +Eggs, scrambled (R)
    +Food bar, almond crunch (NF)
    +Food bar, chocolate chip (NF)
    +Food bar, granola (NF)
    +Food bar, granola/raisin (NF)
    +Food bar, peanut butter/granola (NF)
    +Frankfurters (Vienna sausage) (T)
    +Fruitcake (NF)
    +Fruit cocktail (T)
    +Green beans, french w/mushrooms (R)
    +Green beans and broccoli (R)
    +Ham (I) (T)
    +Jam/Jelly (T)
    +Macaroni and cheese (R)
    +Meatballs w/barbeque sauce (T)
    +Nuts, almonds (NF)
    +Nuts, cashews (NF)
    +Nuts, peanuts (NF)
    +
    +Peach ambrosia (R)
    +Peaches, dried (IM)
    +Peaches, (T)
    +Peanut butter
    +Pears (FD)
    +Pears (T)
    +Peas w/butter sauce (R)
    +Pineapple, crushed (T)
    +Pudding, butterscotch (T)
    +Pudding, chocolate (R) (T)
    +Pudding, lemon (T)
    +Pudding, vanilla (R) (T)
    +Rice pilaf (R)
    +Salmon (T)
    +Sausage patty (R)
    +Shrimp creole (R)
    +Shrimp cocktail (R)
    +Soup, cream of mushroom (R)
    +Spaghetti w/meatless sauce (R)
    +Strawberries (R)
    +Tomatoes, stewed (T)
    +Tuna (T)
    +Turkey and gravy (T)
    +Turkey, smoked/sliced (I) (T)
    +Turkey tetrazzini (R)
    +Vegetables, mixed Italian (R)
    +
    +Beverages
    +
    +Apple drink
    +Cocoa
    +Coffee, black
    +Coffee w/cream
    +Coffee w/cream and sugar
    +Coffee w/sugar
    +Grape drink
    +Grapefruit drink
    +Instant breakfast, chocolate
    +Instant breakfast, strawberry
    +
    +Instant breakfast, vanilla
    +Lemonade
    +Orange drink
    +Orange-grapefruit drink
    +Orange-pineapple drink
    +Strawberry drink
    +Tea
    +Tea w/lemon and sugar
    +Tea w/sugar
    +Tropical punch
    +
    +Condiments
    +
    +Barbeque sauce
    +Catsup
    +Mustard
    +Pepper
    +Salt
    +Hot pepper sauce
    +Mayonnaise
    +
    +*Abbreviations in parentheses indicate type of food T = thermostabilized, I = irradiated, IM = intermediate moisture, FD = freeze dried, R = rehydratable, and NF = natural form.
    +
    +Shuttle Menu
    +
    +The Space Shuttle menu currently features more than 70 food items and 20 beverages. Shuttle travelers will have a varied menu every day for six days rather than the personal preference meals used in previous space missions. Each day, three meals are allowed, with a repeat of menus after six days. The pantry also provides plenty of foods for snacks and between meal beverages and for individual menu changes. The pantry also stores additional contingency food to last 96 hours.
    +
    +Food System Constraints
    +
    +The primary objective in designing a food system for the Space Shuttle is to provide food that is safe and nutritious, light in weight and compact, and is packaged in a convenient form that allows easy manipulation in the weightless environment of an orbiting spacecraft. To achieve this objective requires a careful consideration of three important factors: biological, operational, and engineering. Under each factor are many constraints that affect the final choice of food and how it is

    Our run: davanstrien/ocr-demo-results. 7 pages, 2.4 minutes of processing on a10g-small, after a few minutes of setup.

    +

    Transcribe four minutes of a NASA podcast, with speaker tags and word timestamps, into your own Bucket.

    hf buckets create your-username/transcripts --private
    +hf jobs uv run --timeout 45m \
    +    -v hf://buckets/uv-scripts/transcription-demo/podcast:/input:ro \
    +    -v hf://buckets/your-username/transcripts/podcast:/output \
    +    https://huggingface.co/datasets/uv-scripts/transcription/raw/main/nemotron-transcribe.py \
    +    /input /output --timestamps
    <spk:0> Jim, thank you so much for coming on the podcast today. ... <spk:3> It is, uh, the mission control room, of course, is now open for business ...

    Our run: about 7.5 minutes on rtx-pro-6000, about $0.34. Most of that was model setup.

    +

    Embed the first 100 IMDb reviews and save them as a private dataset.

    hf jobs uv run --flavor l4x1 -s HF_TOKEN \
    +    https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/generate-embeddings.py \
    +    stanfordnlp/imdb your-username/imdb-embeddings \
    +    --column text --max-samples 100 --private

    One L4 GPU embeds about 900 rows per second with all-MiniLM-L6-v2.

    +
    +

    You need the hf CLI (1.32 or newer), a login and pay-as-you-go credit. Add --dry-run to see the GPU and settings without starting a job.

    +

    Find your model

    +

    In the commands, INPUT and OUTPUT are dataset IDs unless the recipe says otherwise.

    + + + +{{GROUPS}} +
    +

    Data tools with no model

      {{TOOLS}}
    +

    For agents

    +

    Read AGENTS.md and recipes.json.

    +
    +
    + + + From 37ab46377204cff7ba8fbbdca02598d7dcf1ea7f Mon Sep 17 00:00:00 2001 From: Daniel van Strien Date: Fri, 30 Oct 2026 13:46:07 +0000 Subject: [PATCH 02/10] tools/build-catalog: satisfy ruff Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016isSPpM5PRqNUzwsDntoG4 --- tools/build-catalog.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) mode change 100644 => 100755 tools/build-catalog.py diff --git a/tools/build-catalog.py b/tools/build-catalog.py old mode 100644 new mode 100755 index e6318c8..196a129 --- a/tools/build-catalog.py +++ b/tools/build-catalog.py @@ -91,9 +91,9 @@ def read_arguments(tree): """Return module string constants and the add_argument calls, using only the syntax tree.""" constants = {} for node in tree.body: - if isinstance(node, ast.Assign) and len(node.targets) == 1 and isinstance(node.targets[0], ast.Name): - if isinstance(node.value, ast.Constant) and isinstance(node.value.value, str): - constants[node.targets[0].id] = node.value.value + is_single_assign = isinstance(node, ast.Assign) and len(node.targets) == 1 and isinstance(node.targets[0], ast.Name) + if is_single_assign and isinstance(node.value, ast.Constant) and isinstance(node.value.value, str): + constants[node.targets[0].id] = node.value.value arguments = [] for node in ast.walk(tree): From 38411c53d9f2c2e5c8700c01643a06677e25bdb6 Mon Sep 17 00:00:00 2001 From: Daniel van Strien Date: Fri, 30 Oct 2026 13:49:34 +0000 Subject: [PATCH 03/10] run-on-jobs: open the intro to fine-tuning, add setup steps for agents Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016isSPpM5PRqNUzwsDntoG4 --- run-on-jobs/AGENTS.md | 25 +++++++++++++++++++++++-- run-on-jobs/index.html | 4 ++-- tools/build-catalog.py | 25 +++++++++++++++++++++++-- tools/run-on-jobs-template.html | 4 ++-- 4 files changed, 50 insertions(+), 8 deletions(-) diff --git a/run-on-jobs/AGENTS.md b/run-on-jobs/AGENTS.md index b19686d..f89fb52 100644 --- a/run-on-jobs/AGENTS.md +++ b/run-on-jobs/AGENTS.md @@ -1,9 +1,30 @@ # Run a model on Hugging Face Jobs -`recipes.json` lists one-command batch recipes. Find the model in `recipes[].models`. +`recipes.json` lists one-command batch and fine-tuning recipes. + +## Set up + +Check for the `hf` CLI (1.32 or newer) with `hf version`. If it's missing, install it, then ask the user to sign in: + + curl -LsSf https://hf.co/cli/install.sh | bash + hf auth login + +Jobs need pay-as-you-go credit on the user's account, and each job costs money, so confirm with the user before starting one. + +Learn the commands from the CLI, because it stays current: + + hf --help + hf jobs uv run --help + hf jobs hardware + +For a persistent reference, install the `hf-cli` skill with `hf skills add`. The installer above adds it by default. + +## Find a recipe hf download uv-scripts/run-on-jobs recipes.json --repo-type space +Find the model in `recipes[].models`. + Each recipe has: - `kind`: `run` applies a model to data; `train` fine-tunes one. @@ -13,7 +34,7 @@ Each recipe has: - `documented`: an example from the script's docs. It may set its own hardware flags. - `flags-needed`: `command` is null. Read the script and choose the options yourself. -Before you start a job: +## Run it 1. Read the options: open the recipe's `url`. 2. Preview without spending: `hf jobs uv run --dry-run `. Check the image and flavor; without a header a GPU recipe can resolve to `cpu-basic`. diff --git a/run-on-jobs/index.html b/run-on-jobs/index.html index 64fe801..cab1ef0 100644 --- a/run-on-jobs/index.html +++ b/run-on-jobs/index.html @@ -81,8 +81,8 @@
    -

    Run Hub models on your own data

    -

    One command starts a GPU on Hugging Face Jobs, runs the model over your whole dataset and saves the results to the Hub. There is nothing to clone.

    +

    Use Hub models on your own data

    +

    Run a model over your whole dataset, or fine-tune it on your own labels. One command starts a GPU on Hugging Face Jobs and saves the results to the Hub. There is nothing to clone.

    Read seven scanned NASA pages with GLM-OCR and save the text to a new dataset on your account.

    hf jobs uv run \
    diff --git a/tools/build-catalog.py b/tools/build-catalog.py
    index 196a129..7752cb5 100755
    --- a/tools/build-catalog.py
    +++ b/tools/build-catalog.py
    @@ -318,10 +318,31 @@ def render_readme(recipes):
     def render_agents():
         return """# Run a model on Hugging Face Jobs
     
    -`recipes.json` lists one-command batch recipes. Find the model in `recipes[].models`.
    +`recipes.json` lists one-command batch and fine-tuning recipes.
    +
    +## Set up
    +
    +Check for the `hf` CLI (1.32 or newer) with `hf version`. If it's missing, install it, then ask the user to sign in:
    +
    +    curl -LsSf https://hf.co/cli/install.sh | bash
    +    hf auth login
    +
    +Jobs need pay-as-you-go credit on the user's account, and each job costs money, so confirm with the user before starting one.
    +
    +Learn the commands from the CLI, because it stays current:
    +
    +    hf --help
    +    hf jobs uv run --help
    +    hf jobs hardware
    +
    +For a persistent reference, install the `hf-cli` skill with `hf skills add`. The installer above adds it by default.
    +
    +## Find a recipe
     
         hf download uv-scripts/run-on-jobs recipes.json --repo-type space
     
    +Find the model in `recipes[].models`.
    +
     Each recipe has:
     
     - `kind`: `run` applies a model to data; `train` fine-tunes one.
    @@ -331,7 +352,7 @@ def render_agents():
       - `documented`: an example from the script's docs. It may set its own hardware flags.
       - `flags-needed`: `command` is null. Read the script and choose the options yourself.
     
    -Before you start a job:
    +## Run it
     
     1. Read the options: open the recipe's `url`.
     2. Preview without spending: `hf jobs uv run --dry-run  `. Check the image and flavor; without a header a GPU recipe can resolve to `cpu-basic`.
    diff --git a/tools/run-on-jobs-template.html b/tools/run-on-jobs-template.html
    index cb74182..0cf2ac4 100644
    --- a/tools/run-on-jobs-template.html
    +++ b/tools/run-on-jobs-template.html
    @@ -81,8 +81,8 @@
     
     
     
    -

    Run Hub models on your own data

    -

    One command starts a GPU on Hugging Face Jobs, runs the model over your whole dataset and saves the results to the Hub. There is nothing to clone.

    +

    Use Hub models on your own data

    +

    Run a model over your whole dataset, or fine-tune it on your own labels. One command starts a GPU on Hugging Face Jobs and saves the results to the Hub. There is nothing to clone.

    Read seven scanned NASA pages with GLM-OCR and save the text to a new dataset on your account.

    hf jobs uv run \
    
    From f7d9e1cd1c73684245f6c45f0ba3361bcd7153fb Mon Sep 17 00:00:00 2001
    From: Daniel van Strien 
    Date: Fri, 30 Oct 2026 13:50:05 +0000
    Subject: [PATCH 04/10] run-on-jobs: keep AGENTS.md to short pointers
    
    Co-Authored-By: Claude Opus 5.5 
    Claude-Session: https://claude.ai/code/session_016isSPpM5PRqNUzwsDntoG4
    ---
     run-on-jobs/AGENTS.md  | 48 ++++++------------------------------------
     tools/build-catalog.py | 48 ++++++------------------------------------
     2 files changed, 14 insertions(+), 82 deletions(-)
    
    diff --git a/run-on-jobs/AGENTS.md b/run-on-jobs/AGENTS.md
    index f89fb52..498be9f 100644
    --- a/run-on-jobs/AGENTS.md
    +++ b/run-on-jobs/AGENTS.md
    @@ -1,43 +1,9 @@
     # Run a model on Hugging Face Jobs
     
    -`recipes.json` lists one-command batch and fine-tuning recipes.
    -
    -## Set up
    -
    -Check for the `hf` CLI (1.32 or newer) with `hf version`. If it's missing, install it, then ask the user to sign in:
    -
    -    curl -LsSf https://hf.co/cli/install.sh | bash
    -    hf auth login
    -
    -Jobs need pay-as-you-go credit on the user's account, and each job costs money, so confirm with the user before starting one.
    -
    -Learn the commands from the CLI, because it stays current:
    -
    -    hf --help
    -    hf jobs uv run --help
    -    hf jobs hardware
    -
    -For a persistent reference, install the `hf-cli` skill with `hf skills add`. The installer above adds it by default.
    -
    -## Find a recipe
    -
    -    hf download uv-scripts/run-on-jobs recipes.json --repo-type space
    -
    -Find the model in `recipes[].models`.
    -
    -Each recipe has:
    -
    -- `kind`: `run` applies a model to data; `train` fine-tunes one.
    -- `command`: the command to start from. `INPUT` and `OUTPUT` are usually dataset IDs; read the script to confirm.
    -- `source`: how far to trust the command.
    -  - `header`: the script carries its launch settings.
    -  - `documented`: an example from the script's docs. It may set its own hardware flags.
    -  - `flags-needed`: `command` is null. Read the script and choose the options yourself.
    -
    -## Run it
    -
    -1. Read the options: open the recipe's `url`.
    -2. Preview without spending: `hf jobs uv run --dry-run  `. Check the image and flavor; without a header a GPU recipe can resolve to `cpu-basic`.
    -3. Start small: pass `--max-samples` if the script has it.
    -4. Monitor: `hf jobs ps`, `hf jobs logs `.
    -5. Check the output. A completed job is not proof that its rows are correct.
    +- **Set up:** `hf version` (needs 1.32+). If missing: `curl -LsSf https://hf.co/cli/install.sh | bash`, then `hf auth login`. Jobs need pay-as-you-go credit.
    +- **Learn the CLI:** `hf --help`, `hf jobs uv run --help`, `hf jobs hardware`. Install the skill with `hf skills add`.
    +- **Find a recipe:** `hf download uv-scripts/run-on-jobs recipes.json --repo-type space`, then look for the model in `recipes[].models`.
    +- **Trust the command by `source`:** `header` carries its launch settings; `documented` is an example from the script's docs; `flags-needed` has no command, so read the script.
    +- **Preview for free:** `hf jobs uv run --dry-run  `. Check the flavor: without a header, a GPU recipe can resolve to `cpu-basic`.
    +- **Spend carefully:** confirm with the user first, and start small with `--max-samples` if the script has it.
    +- **Check the result:** `hf jobs ps`, `hf jobs logs `, then look at the output rows. A completed job doesn't prove they're correct.
    diff --git a/tools/build-catalog.py b/tools/build-catalog.py
    index 7752cb5..ea823b1 100755
    --- a/tools/build-catalog.py
    +++ b/tools/build-catalog.py
    @@ -318,47 +318,13 @@ def render_readme(recipes):
     def render_agents():
         return """# Run a model on Hugging Face Jobs
     
    -`recipes.json` lists one-command batch and fine-tuning recipes.
    -
    -## Set up
    -
    -Check for the `hf` CLI (1.32 or newer) with `hf version`. If it's missing, install it, then ask the user to sign in:
    -
    -    curl -LsSf https://hf.co/cli/install.sh | bash
    -    hf auth login
    -
    -Jobs need pay-as-you-go credit on the user's account, and each job costs money, so confirm with the user before starting one.
    -
    -Learn the commands from the CLI, because it stays current:
    -
    -    hf --help
    -    hf jobs uv run --help
    -    hf jobs hardware
    -
    -For a persistent reference, install the `hf-cli` skill with `hf skills add`. The installer above adds it by default.
    -
    -## Find a recipe
    -
    -    hf download uv-scripts/run-on-jobs recipes.json --repo-type space
    -
    -Find the model in `recipes[].models`.
    -
    -Each recipe has:
    -
    -- `kind`: `run` applies a model to data; `train` fine-tunes one.
    -- `command`: the command to start from. `INPUT` and `OUTPUT` are usually dataset IDs; read the script to confirm.
    -- `source`: how far to trust the command.
    -  - `header`: the script carries its launch settings.
    -  - `documented`: an example from the script's docs. It may set its own hardware flags.
    -  - `flags-needed`: `command` is null. Read the script and choose the options yourself.
    -
    -## Run it
    -
    -1. Read the options: open the recipe's `url`.
    -2. Preview without spending: `hf jobs uv run --dry-run  `. Check the image and flavor; without a header a GPU recipe can resolve to `cpu-basic`.
    -3. Start small: pass `--max-samples` if the script has it.
    -4. Monitor: `hf jobs ps`, `hf jobs logs `.
    -5. Check the output. A completed job is not proof that its rows are correct.
    +- **Set up:** `hf version` (needs 1.32+). If missing: `curl -LsSf https://hf.co/cli/install.sh | bash`, then `hf auth login`. Jobs need pay-as-you-go credit.
    +- **Learn the CLI:** `hf --help`, `hf jobs uv run --help`, `hf jobs hardware`. Install the skill with `hf skills add`.
    +- **Find a recipe:** `hf download uv-scripts/run-on-jobs recipes.json --repo-type space`, then look for the model in `recipes[].models`.
    +- **Trust the command by `source`:** `header` carries its launch settings; `documented` is an example from the script's docs; `flags-needed` has no command, so read the script.
    +- **Preview for free:** `hf jobs uv run --dry-run  `. Check the flavor: without a header, a GPU recipe can resolve to `cpu-basic`.
    +- **Spend carefully:** confirm with the user first, and start small with `--max-samples` if the script has it.
    +- **Check the result:** `hf jobs ps`, `hf jobs logs `, then look at the output rows. A completed job doesn't prove they're correct.
     """
     
     
    
    From f4367992057f82fcc2ed36e0de12f17f6ea0f580 Mon Sep 17 00:00:00 2001
    From: Daniel van Strien 
    Date: Fri, 30 Oct 2026 13:51:15 +0000
    Subject: [PATCH 05/10] run-on-jobs: add usage pointers to AGENTS.md
    
    Co-Authored-By: Claude Opus 5.5 
    Claude-Session: https://claude.ai/code/session_016isSPpM5PRqNUzwsDntoG4
    ---
     run-on-jobs/AGENTS.md  | 41 ++++++++++++++++++++++++++++++++++-------
     tools/build-catalog.py | 41 ++++++++++++++++++++++++++++++++++-------
     2 files changed, 68 insertions(+), 14 deletions(-)
    
    diff --git a/run-on-jobs/AGENTS.md b/run-on-jobs/AGENTS.md
    index 498be9f..97b769c 100644
    --- a/run-on-jobs/AGENTS.md
    +++ b/run-on-jobs/AGENTS.md
    @@ -1,9 +1,36 @@
     # Run a model on Hugging Face Jobs
     
    -- **Set up:** `hf version` (needs 1.32+). If missing: `curl -LsSf https://hf.co/cli/install.sh | bash`, then `hf auth login`. Jobs need pay-as-you-go credit.
    -- **Learn the CLI:** `hf --help`, `hf jobs uv run --help`, `hf jobs hardware`. Install the skill with `hf skills add`.
    -- **Find a recipe:** `hf download uv-scripts/run-on-jobs recipes.json --repo-type space`, then look for the model in `recipes[].models`.
    -- **Trust the command by `source`:** `header` carries its launch settings; `documented` is an example from the script's docs; `flags-needed` has no command, so read the script.
    -- **Preview for free:** `hf jobs uv run --dry-run  `. Check the flavor: without a header, a GPU recipe can resolve to `cpu-basic`.
    -- **Spend carefully:** confirm with the user first, and start small with `--max-samples` if the script has it.
    -- **Check the result:** `hf jobs ps`, `hf jobs logs `, then look at the output rows. A completed job doesn't prove they're correct.
    +Each recipe is one script, run from its URL with `hf jobs uv run`. There is nothing to clone or install except the `hf` CLI.
    +
    +## Set up
    +
    +- Check `hf version` (needs 1.32+). If it's missing: `curl -LsSf https://hf.co/cli/install.sh | bash`, then `hf auth login`.
    +- Jobs need pay-as-you-go credit, and each job costs money. Confirm with the user before starting one.
    +- The CLI is the current reference: `hf --help`, `hf jobs uv run --help`, `hf jobs hardware`. For a skill, use `hf skills add`.
    +
    +## Find a recipe
    +
    +- `hf download uv-scripts/run-on-jobs recipes.json --repo-type space`, then look for the model in `recipes[].models`.
    +- `kind`: `run` applies a model to data; `train` fine-tunes one.
    +- `source`: `header` carries its launch settings; `documented` is an example from the script's docs; `flags-needed` has no command, so read the script first.
    +- Read a script's docstring and options: `curl -s  | head -100`. Running it locally may fail on GPU-only dependencies.
    +- Each task's README explains its recipes, for example https://huggingface.co/datasets/uv-scripts/ocr. OCR also has `models.json`, with language coverage and support levels.
    +
    +## Run it
    +
    +Most recipes go from dataset to dataset:
    +
    +    hf jobs uv run    --max-samples 10
    +
    +Recipes that read files use mounts. A local folder also works as a source:
    +
    +    hf jobs uv run -v hf://buckets//:/input:ro -v hf://buckets//:/output  /input /output
    +
    +- Preview for free with `--dry-run`, and check the flavor: without a header, a GPU recipe can resolve to `cpu-basic`.
    +- Flags before the URL configure the job and override the header, such as `--flavor` and `--timeout`. Flags after it go to the script. If a script flag has the same name as a job flag, put `--` before the URL.
    +- Start with a small `--max-samples` if the script has it, and add `--private` if the output shouldn't be public.
    +
    +## Check it
    +
    +- Use `--detach` for long runs, then `hf jobs logs -f `, `hf jobs wait ` or `hf jobs inspect `. `hf jobs cancel ` stops one.
    +- Look at the output rows. A completed job doesn't prove they're correct.
    diff --git a/tools/build-catalog.py b/tools/build-catalog.py
    index ea823b1..5665f46 100755
    --- a/tools/build-catalog.py
    +++ b/tools/build-catalog.py
    @@ -318,13 +318,40 @@ def render_readme(recipes):
     def render_agents():
         return """# Run a model on Hugging Face Jobs
     
    -- **Set up:** `hf version` (needs 1.32+). If missing: `curl -LsSf https://hf.co/cli/install.sh | bash`, then `hf auth login`. Jobs need pay-as-you-go credit.
    -- **Learn the CLI:** `hf --help`, `hf jobs uv run --help`, `hf jobs hardware`. Install the skill with `hf skills add`.
    -- **Find a recipe:** `hf download uv-scripts/run-on-jobs recipes.json --repo-type space`, then look for the model in `recipes[].models`.
    -- **Trust the command by `source`:** `header` carries its launch settings; `documented` is an example from the script's docs; `flags-needed` has no command, so read the script.
    -- **Preview for free:** `hf jobs uv run --dry-run  `. Check the flavor: without a header, a GPU recipe can resolve to `cpu-basic`.
    -- **Spend carefully:** confirm with the user first, and start small with `--max-samples` if the script has it.
    -- **Check the result:** `hf jobs ps`, `hf jobs logs `, then look at the output rows. A completed job doesn't prove they're correct.
    +Each recipe is one script, run from its URL with `hf jobs uv run`. There is nothing to clone or install except the `hf` CLI.
    +
    +## Set up
    +
    +- Check `hf version` (needs 1.32+). If it's missing: `curl -LsSf https://hf.co/cli/install.sh | bash`, then `hf auth login`.
    +- Jobs need pay-as-you-go credit, and each job costs money. Confirm with the user before starting one.
    +- The CLI is the current reference: `hf --help`, `hf jobs uv run --help`, `hf jobs hardware`. For a skill, use `hf skills add`.
    +
    +## Find a recipe
    +
    +- `hf download uv-scripts/run-on-jobs recipes.json --repo-type space`, then look for the model in `recipes[].models`.
    +- `kind`: `run` applies a model to data; `train` fine-tunes one.
    +- `source`: `header` carries its launch settings; `documented` is an example from the script's docs; `flags-needed` has no command, so read the script first.
    +- Read a script's docstring and options: `curl -s  | head -100`. Running it locally may fail on GPU-only dependencies.
    +- Each task's README explains its recipes, for example https://huggingface.co/datasets/uv-scripts/ocr. OCR also has `models.json`, with language coverage and support levels.
    +
    +## Run it
    +
    +Most recipes go from dataset to dataset:
    +
    +    hf jobs uv run    --max-samples 10
    +
    +Recipes that read files use mounts. A local folder also works as a source:
    +
    +    hf jobs uv run -v hf://buckets//:/input:ro -v hf://buckets//:/output  /input /output
    +
    +- Preview for free with `--dry-run`, and check the flavor: without a header, a GPU recipe can resolve to `cpu-basic`.
    +- Flags before the URL configure the job and override the header, such as `--flavor` and `--timeout`. Flags after it go to the script. If a script flag has the same name as a job flag, put `--` before the URL.
    +- Start with a small `--max-samples` if the script has it, and add `--private` if the output shouldn't be public.
    +
    +## Check it
    +
    +- Use `--detach` for long runs, then `hf jobs logs -f `, `hf jobs wait ` or `hf jobs inspect `. `hf jobs cancel ` stops one.
    +- Look at the output rows. A completed job doesn't prove they're correct.
     """
     
     
    
    From f3683e9a8dbbfb995859c1f5fa1f05f79bff6e37 Mon Sep 17 00:00:00 2001
    From: Daniel van Strien 
    Date: Fri, 30 Oct 2026 13:52:39 +0000
    Subject: [PATCH 06/10] run-on-jobs: say examples rather than labels in the
     intro
    
    Co-Authored-By: Claude Opus 5.5 
    Claude-Session: https://claude.ai/code/session_016isSPpM5PRqNUzwsDntoG4
    ---
     run-on-jobs/index.html          | 2 +-
     tools/run-on-jobs-template.html | 2 +-
     2 files changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/run-on-jobs/index.html b/run-on-jobs/index.html
    index cab1ef0..ed7c87e 100644
    --- a/run-on-jobs/index.html
    +++ b/run-on-jobs/index.html
    @@ -82,7 +82,7 @@
     
     

    Use Hub models on your own data

    -

    Run a model over your whole dataset, or fine-tune it on your own labels. One command starts a GPU on Hugging Face Jobs and saves the results to the Hub. There is nothing to clone.

    +

    Run a model over your whole dataset, or fine-tune it on your own examples. One command starts a GPU on Hugging Face Jobs and saves the results to the Hub. There is nothing to clone.

    Read seven scanned NASA pages with GLM-OCR and save the text to a new dataset on your account.

    hf jobs uv run \
    diff --git a/tools/run-on-jobs-template.html b/tools/run-on-jobs-template.html
    index 0cf2ac4..ee41626 100644
    --- a/tools/run-on-jobs-template.html
    +++ b/tools/run-on-jobs-template.html
    @@ -82,7 +82,7 @@
     
     

    Use Hub models on your own data

    -

    Run a model over your whole dataset, or fine-tune it on your own labels. One command starts a GPU on Hugging Face Jobs and saves the results to the Hub. There is nothing to clone.

    +

    Run a model over your whole dataset, or fine-tune it on your own examples. One command starts a GPU on Hugging Face Jobs and saves the results to the Hub. There is nothing to clone.

    Read seven scanned NASA pages with GLM-OCR and save the text to a new dataset on your account.

    hf jobs uv run \
    
    From 33d989fd118d1f67ebf4dfb1db85e4fdec999fe4 Mon Sep 17 00:00:00 2001
    From: Daniel van Strien 
    Date: Fri, 30 Oct 2026 14:00:33 +0000
    Subject: [PATCH 07/10] run-on-jobs: take commands from script docs and
     arguments, apply review fixes
    
    Header recipes now keep their documented arguments and mounts, and path
    arguments get generated mounts, so no command is hard-coded. Clearer labels,
    intro and placeholders; clipboard fallback; reduced motion.
    
    Co-Authored-By: Claude Opus 5.5 
    Claude-Session: https://claude.ai/code/session_016isSPpM5PRqNUzwsDntoG4
    ---
     run-on-jobs/AGENTS.md           |   4 +-
     run-on-jobs/README.md           |   2 +-
     run-on-jobs/index.html          | 167 ++++++++++++++++++++++----------
     run-on-jobs/recipes.json        |  90 ++++++++---------
     tools/build-catalog.py          |  95 ++++++++++++------
     tools/run-on-jobs-template.html |  13 ++-
     6 files changed, 239 insertions(+), 132 deletions(-)
    
    diff --git a/run-on-jobs/AGENTS.md b/run-on-jobs/AGENTS.md
    index 97b769c..da29bcd 100644
    --- a/run-on-jobs/AGENTS.md
    +++ b/run-on-jobs/AGENTS.md
    @@ -6,7 +6,7 @@ Each recipe is one script, run from its URL with `hf jobs uv run`. There is noth
     
     - Check `hf version` (needs 1.32+). If it's missing: `curl -LsSf https://hf.co/cli/install.sh | bash`, then `hf auth login`.
     - Jobs need pay-as-you-go credit, and each job costs money. Confirm with the user before starting one.
    -- The CLI is the current reference: `hf --help`, `hf jobs uv run --help`, `hf jobs hardware`. For a skill, use `hf skills add`.
    +- The CLI is the current reference: `hf --help`, `hf jobs uv run --help`, `hf jobs hardware`. To install the Hugging Face CLI skill, run `hf skills add`.
     
     ## Find a recipe
     
    @@ -18,7 +18,7 @@ Each recipe is one script, run from its URL with `hf jobs uv run`. There is noth
     
     ## Run it
     
    -Most recipes go from dataset to dataset:
    +Start from the recipe's `command` field. Most recipes go from dataset to dataset:
     
         hf jobs uv run    --max-samples 10
     
    diff --git a/run-on-jobs/README.md b/run-on-jobs/README.md
    index 6d72c9c..60b42d9 100644
    --- a/run-on-jobs/README.md
    +++ b/run-on-jobs/README.md
    @@ -5,7 +5,7 @@ colorFrom: blue
     colorTo: gray
     sdk: static
     pinned: false
    -short_description: Run this model over your own data on HF Jobs
    +short_description: Batch-run this model on your own data with HF Jobs
     models:
       - allenai/olmOCR-2-7B-1025-FP8
       - ATH-MaaS/OvisOCR2
    diff --git a/run-on-jobs/index.html b/run-on-jobs/index.html
    index ed7c87e..e8c535d 100644
    --- a/run-on-jobs/index.html
    +++ b/run-on-jobs/index.html
    @@ -77,15 +77,16 @@
     body .more{margin-left:16px}
     
     
    +@media (prefers-reduced-motion:reduce){summary::before{transition:none}}
     
     
     
     

    Use Hub models on your own data

    -

    Run a model over your whole dataset, or fine-tune it on your own examples. One command starts a GPU on Hugging Face Jobs and saves the results to the Hub. There is nothing to clone.

    +

    Run a model over your whole dataset, or fine-tune it on your own examples. Each command starts a paid batch job on Hugging Face Jobs and saves the results to the Hub. There is nothing to clone.

    -

    Read seven scanned NASA pages with GLM-OCR and save the text to a new dataset on your account.

    hf jobs uv run \
    +

    Read seven scanned NASA pages with GLM-OCR and save the text to a new public dataset on your account. Add --private to keep it private.

    hf jobs uv run \
         https://huggingface.co/datasets/uv-scripts/ocr/raw/main/glm-ocr.py \
         uv-scripts/ocr-demo your-username/ocr-demo-results
    The scan
    Scanned page listing Space Shuttle foods
    What the Job wrote
    Space Shuttle Food and Beverage List
     
    @@ -225,96 +226,160 @@ 

    Use Hub models on your own data

    You need the hf CLI (1.32 or newer), a login and pay-as-you-go credit. Add --dry-run to see the GPU and settings without starting a job.

    Find your model

    -

    In the commands, INPUT and OUTPUT are dataset IDs unless the recipe says otherwise.

    +

    Replace the capitalised placeholders and your-username. Check the script if you're unsure what a value should be.

    -

    OCR

    • allenai/olmOCR-2-7B-1025-FP8ready · a10g-small

      olmocr2-vllm.py ready to run · a10g-small

      Convert document images to markdown using olmOCR-2 with vLLM.

      hf jobs uv run \
      +

      OCR

      • allenai/olmOCR-2-7B-1025-FP8command ready · a10g-small

        olmocr2-vllm.py command ready · a10g-small

        Convert document images to markdown using olmOCR-2 with vLLM.

        hf jobs uv run \
             https://huggingface.co/datasets/uv-scripts/ocr/raw/main/olmocr2-vllm.py \
        -    INPUT_DATASET OUTPUT_DATASET
      • ATH-MaaS/OvisOCR2ready · a10g-small

        ovis-ocr2.py ready to run · a10g-small

        Convert document images to markdown using OvisOCR2 with vLLM.

        hf jobs uv run \
        +    INPUT_DATASET OUTPUT_DATASET
      • ATH-MaaS/OvisOCR2command ready · a10g-small

        ovis-ocr2.py command ready · a10g-small

        Convert document images to markdown using OvisOCR2 with vLLM.

        hf jobs uv run \
             https://huggingface.co/datasets/uv-scripts/ocr/raw/main/ovis-ocr2.py \
        -    INPUT_DATASET OUTPUT_DATASET
        1 more recipe

        ovis-ocr2-saturate.py ready to run · a10g-small

        Convert document images to markdown using OvisOCR2 via saturate.

        hf jobs uv run \
        +    INPUT_DATASET OUTPUT_DATASET --batch-size 16
        1 more recipe

        ovis-ocr2-saturate.py command ready · a10g-small

        Convert document images to markdown using OvisOCR2 via saturate.

        hf jobs uv run \
             https://huggingface.co/datasets/uv-scripts/ocr/raw/main/ovis-ocr2-saturate.py \
        -    INPUT_DATASET OUTPUT_DATASET
      • baidu/Qianfan-OCRready · a10g-small

        qianfan-ocr.py ready to run · a10g-small

        Convert document images to markdown using Qianfan-OCR with vLLM.

        hf jobs uv run \
        +    <INPUT_DATASET> <OUTPUT_DATASET>
    • baidu/Qianfan-OCRcommand ready · a10g-small

      qianfan-ocr.py command ready · a10g-small

      Convert document images to markdown using Qianfan-OCR with vLLM.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/qianfan-ocr.py \
      -    INPUT_DATASET OUTPUT_DATASET
    • baidu/Unlimited-OCRready · a10g-small

      unlimited-ocr-vllm.py ready to run · a10g-small

      Convert document images to markdown using Baidu Unlimited-OCR with vLLM.

      hf jobs uv run \
      +    INPUT_DATASET OUTPUT_DATASET --max-samples 10
    • baidu/Unlimited-OCRcommand ready · a10g-small

      unlimited-ocr-vllm.py command ready · a10g-small

      Convert document images to markdown using Baidu Unlimited-OCR with vLLM.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr-vllm.py \
      -    INPUT_DATASET OUTPUT_DATASET
    • baidu/Unlimited-OCR-2ready · rtx-pro-6000

      unlimited-ocr2.py ready to run · rtx-pro-6000

      OCR whole documents (book volumes, folders of scans) with Baidu Unlimited-OCR-2.

      hf jobs uv run \
      +    your-input-dataset your-output-dataset --max-samples 10
    • baidu/Unlimited-OCR-2command ready · rtx-pro-6000

      unlimited-ocr2.py command ready · rtx-pro-6000

      OCR whole documents (book volumes, folders of scans) with Baidu Unlimited-OCR-2.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr2.py \
      -    INPUT OUTPUT
      2 more recipes

      unlimited-ocr2-live.py ready to run, experimental · rtx-pro-6000

      unlimited-ocr2.py with a live view you can watch (and screen-record) while the Job runs.

      hf jobs uv run \
      +    "hf://buckets/biglam/britannica/source/pages/1771EncyclopediaBritannicaNLS/*.jp2" \
      +    <user>/britannica-1771
      2 more recipes

      unlimited-ocr2-live.py command ready, experimental · rtx-pro-6000

      unlimited-ocr2.py with a live view you can watch (and screen-record) while the Job runs.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr2-live.py \
      -    INPUT OUTPUT

      unlimited-ocr2-saturate.py ready to run, experimental · rtx-pro-6000

      OCR whole documents (book volumes, PDFs) with Baidu Unlimited-OCR-2 via saturate.

      hf jobs uv run \
      +    "hf://buckets/biglam/britannica/source/pages/1771EncyclopediaBritannicaNLS/*.jp2" \
      +    <user>/britannica-1771 --live-port 7860

      unlimited-ocr2-saturate.py command ready, experimental · rtx-pro-6000

      OCR whole documents (book volumes, PDFs) with Baidu Unlimited-OCR-2 via saturate.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr2-saturate.py \
      -    INPUT OUTPUT
    • datalab-to/liftready · a100-large

      lift-extract.py ready to run · a100-large

      Extract structured JSON from document images OR multi-page PDFs using Datalab's lift model (datalab-to/lift, 9B, Qwen3.5-based).

      hf jobs uv run \
      +    "hf://buckets/biglam/britannica/source/pages/1771EncyclopediaBritannicaNLS/*.jp2" \
      +    <user>/britannica-1771-uocr2
    • datalab-to/liftcommand ready · a100-large

      lift-extract.py command ready · a100-large

      Extract structured JSON from document images OR multi-page PDFs using Datalab's lift model (datalab-to/lift, 9B, Qwen3.5-based).

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lift-extract.py \
      -    INPUT_DATASET OUTPUT_DATASET --schema SCHEMA
    • datalab-to/surya-ocr-2ready · a10g-small

      surya-ocr.py ready to run · a10g-small

      Document intelligence on images OR multi-page PDFs with Datalab's Surya OCR 2 (datalab-to/surya-ocr-2, 650M, Qwen3.5-style).

      hf jobs uv run \
      +    INPUT_DATASET OUTPUT_DATASET \
      +    --schema '{"type":"object","properties":{"title":{"type":"string"}}}' \
      +    --max-samples 5 --shuffle --seed 42
    • datalab-to/surya-ocr-2command ready · a10g-small

      surya-ocr.py command ready · a10g-small

      Document intelligence on images OR multi-page PDFs with Datalab's Surya OCR 2 (datalab-to/surya-ocr-2, 650M, Qwen3.5-style).

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/surya-ocr.py \
      -    INPUT_DATASET OUTPUT_DATASET
    • deepseek-ai/DeepSeek-OCRready · a10g-small

      deepseek-ocr-vllm.py ready to run · a10g-small

      Convert document images to markdown using DeepSeek-OCR with vLLM.

      hf jobs uv run \
      +    INPUT_DATASET OUTPUT_DATASET \
      +    --max-samples 5 --shuffle --seed 42
    • deepseek-ai/DeepSeek-OCRcommand ready · a10g-small

      deepseek-ocr-vllm.py command ready · a10g-small

      Convert document images to markdown using DeepSeek-OCR with vLLM.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/deepseek-ocr-vllm.py \
      -    INPUT_DATASET OUTPUT_DATASET
    • deepseek-ai/DeepSeek-OCR-2ready · a10g-small

      deepseek-ocr2-vllm.py ready to run · a10g-small

      Convert document images to markdown using DeepSeek-OCR-2 with vLLM.

      hf jobs uv run \
      +    my-dataset my-output --max-samples 10
    • deepseek-ai/DeepSeek-OCR-2command ready · a10g-small

      deepseek-ocr2-vllm.py command ready · a10g-small

      Convert document images to markdown using DeepSeek-OCR-2 with vLLM.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/deepseek-ocr2-vllm.py \
      -    INPUT_DATASET OUTPUT_DATASET
    • lightonai/LightOnOCR-2-1Bready · a10g-small

      lighton-ocr2.py ready to run · a10g-small

      Convert document images to markdown using LightOnOCR-2 with vLLM.

      hf jobs uv run \
      +    my-dataset my-output --max-samples 10
    • lightonai/LightOnOCR-2-1Bcommand ready · a10g-small

      lighton-ocr2.py command ready · a10g-small

      Convert document images to markdown using LightOnOCR-2 with vLLM.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr2.py \
      -    INPUT_DATASET OUTPUT_DATASET
      1 more recipe

      lighton-ocr2-saturate.py ready to run · a10g-small

      Convert document images to markdown using LightOnOCR-2 via saturate.

      hf jobs uv run \
      +    <INPUT_DATASET> <OUTPUT_DATASET>
      1 more recipe

      lighton-ocr2-saturate.py command ready · a10g-small

      Convert document images to markdown using LightOnOCR-2 via saturate.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr2-saturate.py \
      -    INPUT_DATASET OUTPUT_DATASET
    • lightonai/LightOnOCR-3-4Bready · a10g-small

      lighton-ocr3-bucket.py ready to run · a10g-small

      OCR images and PDFs from an HF Bucket (or a directory) using LightOnOCR-3, writing markdown files.

      hf jobs uv run \
      +    <INPUT_DATASET> <OUTPUT_DATASET>
    • lightonai/LightOnOCR-3-4Bcommand ready · a10g-small

      lighton-ocr3-bucket.py command ready · a10g-small

      OCR images and PDFs from an HF Bucket (or a directory) using LightOnOCR-3, writing markdown files.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr3-bucket.py \
      -    INPUT OUTPUT
      1 more recipe

      lighton-ocr3.py ready to run · a10g-small

      Convert document images to markdown (or layout blocks) using LightOnOCR-3 with vLLM.

      hf jobs uv run \
      +    hf://buckets/biglam/britannica/source/pages/00070476bsb \
      +    hf://buckets/your-username/ocr-output/britannica --mode grounding --max-samples 20
      1 more recipe

      lighton-ocr3.py command ready · a10g-small

      Convert document images to markdown (or layout blocks) using LightOnOCR-3 with vLLM.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr3.py \
      -    INPUT_DATASET OUTPUT_DATASET
    • numind/NuExtract3ready · a10g-small

      nuextract3.py ready to run · a10g-small

      Convert document images to markdown OR extract structured JSON using NuExtract3 with vLLM.

      hf jobs uv run \
      +    INPUT_DATASET OUTPUT_DATASET --max-samples 10
    • numind/NuExtract3command ready · a10g-small

      nuextract3.py command ready · a10g-small

      Convert document images to markdown OR extract structured JSON using NuExtract3 with vLLM.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/nuextract3.py \
      -    INPUT_DATASET OUTPUT_DATASET
    • openbmb/MiniCPM-OCR-1.0ready · a10g-large

      minicpm-ocr.py ready to run, experimental · a10g-large

      Convert document images to markdown with OpenBMB's MiniCPM-OCR 1.0 pipeline.

      hf jobs uv run \
      +    INPUT_DATASET OUTPUT_DATASET --max-samples 5 --shuffle --seed 42
    • openbmb/MiniCPM-OCR-1.0command ready · a10g-large

      minicpm-ocr.py command ready, experimental · a10g-large

      Convert document images to markdown with OpenBMB's MiniCPM-OCR 1.0 pipeline.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/minicpm-ocr.py \
      -    INPUT OUTPUT
    • PaddlePaddle/PaddleOCR-VL-1.6ready · a10g-small

      paddleocr-vl-1.6.py ready to run · a10g-small

      Convert document images to text/tables/formulas using PaddleOCR-VL-1.6 with vLLM.

      hf jobs uv run \
      +    INPUT_DATASET OUTPUT_DATASET --max-samples 20
    • PaddlePaddle/PaddleOCR-VL-1.6command ready · a10g-small

      paddleocr-vl-1.6.py command ready · a10g-small

      Convert document images to text/tables/formulas using PaddleOCR-VL-1.6 with vLLM.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/paddleocr-vl-1.6.py \
      -    INPUT_DATASET OUTPUT_DATASET
    • rednote-hilab/dots.mocrready · a10g-small

      dots-mocr.py ready to run · a10g-small

      Convert document images to markdown using dots.mocr with vLLM.

      hf jobs uv run \
      +    INPUT_DATASET OUTPUT_DATASET
    • rednote-hilab/dots.mocrcommand ready · a10g-small

      dots-mocr.py command ready · a10g-small

      Convert document images to markdown using dots.mocr with vLLM.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/dots-mocr.py \
      -    INPUT_DATASET OUTPUT_DATASET
    • rednote-hilab/dots.ocrready · a10g-small

      dots-ocr.py ready to run · a10g-small

      Convert document images to markdown using DoTS.ocr with vLLM.

      hf jobs uv run \
      +    INPUT_DATASET OUTPUT_DATASET
    • rednote-hilab/dots.ocrcommand ready · a10g-small

      dots-ocr.py command ready · a10g-small

      Convert document images to markdown using DoTS.ocr with vLLM.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/dots-ocr.py \
      -    INPUT_DATASET OUTPUT_DATASET
    • tencent/HunyuanOCRready · a10g-small

      hunyuan-ocr-1.5.py ready to run · a10g-small

      Convert document images to markdown using HunyuanOCR-1.5 with vLLM.

      hf jobs uv run \
      +    INPUT_DATASET OUTPUT_DATASET
    • tencent/HunyuanOCRcommand ready · a10g-small

      hunyuan-ocr-1.5.py command ready · a10g-small

      Convert document images to markdown using HunyuanOCR-1.5 with vLLM.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/hunyuan-ocr-1.5.py \
      -    INPUT_DATASET OUTPUT_DATASET
    • zai-org/GLM-OCRready · a10g-small

      glm-ocr.py ready to run · a10g-small

      Convert document images to markdown using GLM-OCR with vLLM.

      hf jobs uv run \
      +    INPUT_DATASET OUTPUT_DATASET
    • zai-org/GLM-OCRcommand ready · a10g-small

      glm-ocr.py command ready · a10g-small

      Convert document images to markdown using GLM-OCR with vLLM.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/ocr/raw/main/glm-ocr.py \
      -    INPUT_DATASET OUTPUT_DATASET

    Transcription

    • CohereLabs/cohere-transcribe-03-2026options needed

      cohere-transcribe-vllm.py set options first

      Transcribe audio files from a directory using Cohere Transcribe via vLLM.

      Read the script for its options. It has no launch settings yet.

      2 more recipes

      cohere-transcribe.py set options first

      Transcribe audio files from a directory using Cohere Transcribe via transformers.

      Read the script for its options. It has no launch settings yet.

      easytranscriber-transcribe.py set options first

      Transcribe audio with word-level timestamps using kb-labb/easytranscriber.

      Read the script for its options. It has no launch settings yet.

    • distil-whisper/distil-large-v3.5options needed

      easytranscriber-transcribe.py set options first

      Transcribe audio with word-level timestamps using kb-labb/easytranscriber.

      Read the script for its options. It has no launch settings yet.

    • facebook/mms-1b-alloptions needed

      easytranscriber-transcribe.py set options first

      Transcribe audio with word-level timestamps using kb-labb/easytranscriber.

      Read the script for its options. It has no launch settings yet.

    • ibm-granite/granite-speech-5.0-470m-turboctcoptions needed

      granite-turboctc-transcribe.py set options first

      Transcribe English audio files with IBM Granite Speech 5.0 TurboCTC (470M).

      Read the script for its options. It has no launch settings yet.

    • nvidia/NVIDIA-Nemotron-3.5-Transcribe-30B-A4Bready · rtx-pro-6000

      nemotron-transcribe.py ready to run · rtx-pro-6000

      Transcribe audio with NVIDIA Nemotron 3.5 Transcribe via an in-job vLLM server.

      hf jobs uv run \
      +    {source_dataset} \
      +    <OUTPUT_DATASET> \
      +    --image-column {image_column} \
      +    --batch-size {batch_size} \
      +    --task {task}

    Transcription

    • CohereLabs/cohere-transcribe-03-2026example command

      cohere-transcribe.py example command

      Transcribe audio files from a directory using Cohere Transcribe via transformers.

      hf jobs uv run --flavor l4x1 \
      +    -s HF_TOKEN \
      +    -v hf://buckets/your-username/audio-input:/input:ro \
      +    -v hf://buckets/your-username/transcripts:/output \
      +    https://huggingface.co/datasets/uv-scripts/transcription/raw/main/cohere-transcribe.py \
      +    /input /output --language en --compile
      2 more recipes

      easytranscriber-transcribe.py example command

      Transcribe audio with word-level timestamps using kb-labb/easytranscriber.

      hf jobs uv run --flavor l4x1 -s HF_TOKEN \
      +    -e UV_TORCH_BACKEND=cu128 \
      +    -v hf://buckets/your-username/audio-files:/input:ro \
      +    -v hf://buckets/your-username/transcripts-aligned:/output \
      +    https://huggingface.co/datasets/uv-scripts/transcription/raw/main/easytranscriber-transcribe.py \
      +    /input /output \
      +    --language en --emit-txt --emit-srt

      cohere-transcribe-vllm.py read the script first

      Transcribe audio files from a directory using Cohere Transcribe via vLLM.

      Read the script for its options. There is no ready-made command yet.

    • distil-whisper/distil-large-v3.5example command

      easytranscriber-transcribe.py example command

      Transcribe audio with word-level timestamps using kb-labb/easytranscriber.

      hf jobs uv run --flavor l4x1 -s HF_TOKEN \
      +    -e UV_TORCH_BACKEND=cu128 \
      +    -v hf://buckets/your-username/audio-files:/input:ro \
      +    -v hf://buckets/your-username/transcripts-aligned:/output \
      +    https://huggingface.co/datasets/uv-scripts/transcription/raw/main/easytranscriber-transcribe.py \
      +    /input /output \
      +    --language en --emit-txt --emit-srt
    • facebook/mms-1b-allexample command

      easytranscriber-transcribe.py example command

      Transcribe audio with word-level timestamps using kb-labb/easytranscriber.

      hf jobs uv run --flavor l4x1 -s HF_TOKEN \
      +    -e UV_TORCH_BACKEND=cu128 \
      +    -v hf://buckets/your-username/audio-files:/input:ro \
      +    -v hf://buckets/your-username/transcripts-aligned:/output \
      +    https://huggingface.co/datasets/uv-scripts/transcription/raw/main/easytranscriber-transcribe.py \
      +    /input /output \
      +    --language en --emit-txt --emit-srt
    • ibm-granite/granite-speech-5.0-470m-turboctcexample command

      granite-turboctc-transcribe.py example command

      Transcribe English audio files with IBM Granite Speech 5.0 TurboCTC (470M).

      hf jobs uv run --flavor l4x1 -s HF_TOKEN \
      +    -e UV_TORCH_BACKEND=cu128 \
      +    -v hf://buckets/your-username/audio-input:/input:ro \
      +    -v hf://buckets/your-username/transcripts:/output \
      +    https://huggingface.co/datasets/uv-scripts/transcription/raw/main/granite-turboctc-transcribe.py \
      +    /input /output
    • nvidia/NVIDIA-Nemotron-3.5-Transcribe-30B-A4Bcommand ready · rtx-pro-6000

      nemotron-transcribe.py command ready · rtx-pro-6000

      Transcribe audio with NVIDIA Nemotron 3.5 Transcribe via an in-job vLLM server.

      hf jobs uv run \
      +    -v hf://buckets/your-username/audio-files:/input:ro \
      +    -v hf://buckets/your-username/transcripts:/output \
           https://huggingface.co/datasets/uv-scripts/transcription/raw/main/nemotron-transcribe.py \
      -    INPUT_DIR OUTPUT_DIR
    • OpenMOSS-Team/MOSS-Transcribe-Diarizeoptions needed

      moss-transcribe-diarize.py set options first

      Transcribe + diarize audio files using MOSS-Transcribe-Diarize (0.9B).

      Read the script for its options. It has no launch settings yet.

      1 more recipe

      moss-transcribe-diarize-server.py set options first

      High-throughput transcription + diarization via an in-job sgl-omni server.

      Read the script for its options. It has no launch settings yet.

    Segmentation

    • facebook/sam3example

      detect-objects.py example from the script

      Detect objects in images using Meta's SAM3 (Segment Anything Model 3).

      hf jobs uv run --flavor a100-large \
      +    /input /output
    • OpenMOSS-Team/MOSS-Transcribe-Diarizeexample command

      moss-transcribe-diarize.py example command

      Transcribe + diarize audio files using MOSS-Transcribe-Diarize (0.9B).

      hf jobs uv run --flavor l4x1 -s HF_TOKEN \
      +    -e UV_TORCH_BACKEND=cu128 \
      +    -v hf://buckets/your-username/audio-files:/input:ro \
      +    -v hf://buckets/your-username/transcripts:/output \
      +    https://huggingface.co/datasets/uv-scripts/transcription/raw/main/moss-transcribe-diarize.py \
      +    /input /output --emit-txt --emit-srt
      1 more recipe

      moss-transcribe-diarize-server.py read the script first

      High-throughput transcription + diarization via an in-job sgl-omni server.

      Read the script for its options. There is no ready-made command yet.

    Segmentation

    • facebook/sam3example command

      detect-objects.py example command

      Detect objects in images using Meta's SAM3 (Segment Anything Model 3).

      hf jobs uv run --flavor a100-large \
           -s HF_TOKEN \
           https://huggingface.co/datasets/uv-scripts/sam3/raw/main/detect-objects.py \
      -    input-dataset output-dataset \
      +    INPUT_DATASET OUTPUT_DATASET \
           --class-name photograph \
      -    --confidence-threshold 0.5
      1 more recipe

      segment-objects.py example from the script

      Segment objects in images using Meta's SAM3 (Segment Anything Model 3).

      hf jobs uv run --flavor a100-large \
      +    --confidence-threshold 0.5
      1 more recipe

      segment-objects.py example command

      Segment objects in images using Meta's SAM3 (Segment Anything Model 3).

      hf jobs uv run --flavor a100-large \
           -s HF_TOKEN \
           https://huggingface.co/datasets/uv-scripts/sam3/raw/main/segment-objects.py \
      -    input-dataset output-dataset \
      -    --class-name photograph

    Object detection

    • Qwen/Qwen3.6-35B-A3Bready · a100-large

      qwen3vl-detect.py ready to run · a100-large

      Instruction-oriented object detection with Qwen3-VL via vLLM.

      hf jobs uv run \
      +    INPUT_DATASET OUTPUT_DATASET \
      +    --class-name photograph

    Object detection

    • Qwen/Qwen3.6-35B-A3Bcommand ready · a100-large

      qwen3vl-detect.py command ready · a100-large

      Instruction-oriented object detection with Qwen3-VL via vLLM.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/vlm-object-detection/raw/main/qwen3vl-detect.py \
      -    INPUT_DATASET OUTPUT_DATASET
      1 more recipe

      qwen3vl-detect-fewshot.py ready to run · a100-large

      [FEW-SHOT VARIANT] Instruction-oriented object detection with Qwen3-VL via vLLM.

      hf jobs uv run \
      +    INPUT_DATASET OUTPUT_DATASET
      1 more recipe

      qwen3vl-detect-fewshot.py command ready · a100-large

      Instruction-oriented object detection with Qwen3-VL via vLLM.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/vlm-object-detection/raw/main/qwen3vl-detect-fewshot.py \
      -    INPUT_DATASET OUTPUT_DATASET

    Video

    • NemoStation/Marlin-2Bready · a10g-small

      marlin-caption.py ready to run · a10g-small

      Caption videos with timestamped events using Marlin-2B, writing a resumable dataset.

      hf jobs uv run \
      +    INPUT_DATASET OUTPUT_DATASET

    Video

    • NemoStation/Marlin-2Bcommand ready · a10g-small

      marlin-caption.py command ready · a10g-small

      Caption videos with timestamped events using Marlin-2B, writing a resumable dataset.

      hf jobs uv run \
      +    -v hf://buckets/your-username/my-videos:/input:ro \
           https://huggingface.co/datasets/uv-scripts/video/raw/main/marlin-caption.py \
      -    INPUT_DIR OUTPUT
    • Qwen/Qwen3.8-27Bready · a100-large

      qwen38-caption.py ready to run · a100-large

      Caption whole videos — no chunking — with Qwen3.8-27B, writing a resumable dataset.

      hf jobs uv run \
      +    /input hf://buckets/your-username/my-videos/captions
    • Qwen/Qwen3.8-27Bcommand ready · a100-large

      qwen38-caption.py command ready · a100-large

      Caption whole videos — no chunking — with Qwen3.8-27B, writing a resumable dataset.

      hf jobs uv run \
      +    -v hf://buckets/your-username/my-videos:/input:ro \
           https://huggingface.co/datasets/uv-scripts/video/raw/main/qwen38-caption.py \
      -    INPUT_DIR OUTPUT

    Classification

    • fastino/gliner2.5-multi-v1ready · t4-small

      classify-gliner2.py ready to run · t4-small

      Classify a text column of a Hub dataset with GLiNER2 — zero-shot, or with your fine-tuned model.

      hf jobs uv run \
      +    /input hf://buckets/your-username/my-videos/captions

    Classification

    • fastino/gliner2.5-multi-v1command ready · t4-small

      classify-gliner2.py command ready · t4-small

      Classify a text column of a Hub dataset with GLiNER2 — zero-shot, or with your fine-tuned model.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/classification/raw/main/classify-gliner2.py \
      -    INPUT_DATASET OUTPUT_DATASET
    • HuggingFaceTB/SmolLM3-3Bready · l4x1

      classify-dataset-sglang.py ready to run · l4x1

      Classify text columns in Hugging Face datasets using SGLang with reasoning-aware models.

      hf jobs uv run \
      +    fancyzhx/ag_news your-username/ag-news-gliner2 \
      +    --labels World Sports Business "Science and technology" --max-samples 1000
    • HuggingFaceTB/SmolLM3-3Bcommand ready · l4x1

      classify-dataset-sglang.py command ready · l4x1

      Classify text columns in Hugging Face datasets using SGLang with reasoning-aware models.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/classification/raw/main/classify-dataset-sglang.py \
      -    --input-dataset INPUT_DATASET --column COLUMN --labels LABELS --output-dataset OUTPUT_DATASET
      1 more recipe

      classify-dataset.py ready to run · l4x1

      Classify text columns in Hugging Face datasets using vLLM with structured outputs.

      hf jobs uv run \
      +    --input-dataset your-username/emails \
      +    --column content \
      +    --labels "spam,ham" \
      +    --output-dataset your-username/emails-classified \
      +    --reasoning
      1 more recipe

      classify-dataset.py command ready · l4x1

      Classify text columns in Hugging Face datasets using vLLM with structured outputs.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/classification/raw/main/classify-dataset.py \
      -    --input-dataset INPUT_DATASET --column COLUMN --labels LABELS --output-dataset OUTPUT_DATASET

    Embeddings

    • BAAI/bge-base-en-v1.5example

      embed-to-lance.py example from the script

      Embed a Hugging Face dataset and push it back as a Lance vector index — a Hub dataset that IS a searchable vector database.

      hf jobs uv run --flavor l4x1 -s HF_TOKEN https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/embed-to-lance.py \
      -    stanfordnlp/imdb your-name/imdb-vecdb --column text --model BAAI/bge-base-en-v1.5 --private
    • Qwen/Qwen3-Embedding-0.6Bexample

      generate-embeddings-vllm.py example from the script

      High-throughput embedding generation with vLLM pooling mode — the "scale" variant of generate-embeddings.py, for large *decoder* embedding models (e.g

      hf jobs uv run --flavor l4x1 -s HF_TOKEN https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/generate-embeddings-vllm.py \
      -    stanfordnlp/imdb your-name/imdb-embeddings --column text --model Qwen/Qwen3-Embedding-0.6B --private
    • sentence-transformers/all-MiniLM-L6-v2example

      generate-embeddings.py example from the script

      Generate embeddings for a Hugging Face dataset (text OR images) with sentence-transformers, and push the result back to the Hub as a new dataset with

      hf jobs uv run --flavor l4x1 -s HF_TOKEN https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/generate-embeddings.py \
      -    stanfordnlp/imdb  your-name/imdb-embeddings \
      -    --column text --model sentence-transformers/all-MiniLM-L6-v2
      1 more recipe

      launch-embedding-fleet.py set options first

      Fan one embedding run out across N Hugging Face Jobs, then consolidate.

      Read the script for its options. It has no launch settings yet.

    Text generation

    • Qwen/Qwen2-VL-7B-Instructready · l40sx1

      vlm-classify.py ready to run · l40sx1

      Classify images using Vision Language Models with vLLM.

      hf jobs uv run \
      +    --input-dataset your-username/emails \
      +    --column content \
      +    --labels "spam,ham" \
      +    --output-dataset your-username/emails-classified \
      +    --enable-reasoning

    Embeddings

    • BAAI/bge-base-en-v1.5example command

      embed-to-lance.py example command

      Embed a Hugging Face dataset and push it back as a Lance vector index — a Hub dataset that IS a searchable vector database.

      hf jobs uv run --flavor l4x1 -s HF_TOKEN \
      +    https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/embed-to-lance.py \
      +    stanfordnlp/imdb your-username/imdb-vecdb --column text --model BAAI/bge-base-en-v1.5 --private
    • Qwen/Qwen3-Embedding-0.6Bexample command

      generate-embeddings-vllm.py example command

      High-throughput embedding generation with vLLM pooling mode — the "scale" variant of generate-embeddings.py, for large decoder embedding models (e.g.

      hf jobs uv run --flavor l4x1 -s HF_TOKEN \
      +    https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/generate-embeddings-vllm.py \
      +    stanfordnlp/imdb your-username/imdb-embeddings --column text --model Qwen/Qwen3-Embedding-0.6B --private
    • sentence-transformers/all-MiniLM-L6-v2example command

      generate-embeddings.py example command

      Generate embeddings for a Hugging Face dataset (text OR images) with sentence-transformers, and push the result back to the Hub as a new dataset with…

      hf jobs uv run --flavor l4x1 -s HF_TOKEN \
      +    https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/generate-embeddings.py \
      +    stanfordnlp/imdb  your-username/imdb-embeddings \
      +    --column text --model sentence-transformers/all-MiniLM-L6-v2
      1 more recipe

      launch-embedding-fleet.py read the script first

      Fan one embedding run out across N Hugging Face Jobs, then consolidate.

      Read the script for its options. There is no ready-made command yet.

    Text generation

    • Qwen/Qwen2-VL-7B-Instructcommand ready · l40sx1

      vlm-classify.py command ready · l40sx1

      Classify images using Vision Language Models with vLLM.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/vllm/raw/main/vlm-classify.py \
      -    INPUT_DATASET OUTPUT_DATASET --classes CLASSES
    • Qwen/Qwen3-30B-A3B-Instruct-2507ready · a100-large

      generate-responses.py ready to run · a100-large

      Generate responses for prompts in a dataset using vLLM for efficient GPU inference.

      hf jobs uv run \
      +    your-username/INPUT_DATASET \
      +    your-username/OUTPUT_DATASET \
      +    --classes "title-page,content,index,other"
    • Qwen/Qwen3-30B-A3B-Instruct-2507command ready · a100-large

      generate-responses.py command ready · a100-large

      Generate responses for prompts in a dataset using vLLM for efficient GPU inference.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/vllm/raw/main/generate-responses.py \
      -    SRC_DATASET_HUB_ID OUTPUT_DATASET_HUB_ID

    Fine-tuning

    • fastino/gliner2.5-multi-v1ready · t4-small

      train-gliner2.py ready to run · t4-small

      Fine-tune GLiNER2 into a text classifier — a small model (74M to 287M parameters, depending on the base checkpoint) that already works zero-shot.

      hf jobs uv run \
      +    input output --max-model-len 32768

    Fine-tuning

    • fastino/gliner2.5-multi-v1command ready · t4-small

      train-gliner2.py command ready · t4-small

      Fine-tune GLiNER2 into a text classifier — a small model (74M to 287M parameters, depending on the base checkpoint) that already works zero-shot.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-gliner2.py \
      -    INPUT_DATASET OUTPUT_REPO
    • LiquidAI/LFM2.5-Encoder-350Mready · l4x1

      train-classifier.py ready to run · l4x1

      Fine-tune a text-classification encoder on a Hub dataset and push the trained model to the Hub.

      hf jobs uv run \
      +    biglam/blbooksgenre your-username/gliner2-blbooks-genre \
      +    --dataset-config title_genre_classifiction --text-column title
    • LiquidAI/LFM2.5-Encoder-350Mcommand ready · l4x1

      train-classifier.py command ready · l4x1

      Fine-tune a text-classification encoder on a Hub dataset and push the trained model to the Hub.

      hf jobs uv run \
           https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-classifier.py \
      -    INPUT_DATASET OUTPUT_REPO
    • sentence-transformers/all-MiniLM-L6-v2example

      train-setfit.py example from the script

      Few-shot text classification with SetFit — train on 8-64 labelled examples per class, on CPU or GPU.

      hf jobs uv run --flavor cpu-basic --secrets HF_TOKEN \
      +    fancyzhx/ag_news your-username/my-news-classifier \
      +    --max-samples 2000 --epochs 1
    • sentence-transformers/all-MiniLM-L6-v2example command

      train-setfit.py example command

      Few-shot text classification with SetFit — train on 8-64 labelled examples per class, on CPU or GPU.

      hf jobs uv run --flavor cpu-basic --secrets HF_TOKEN \
           https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-setfit.py \
      -    fancyzhx/ag_news username/ag-news-setfit \
      +    fancyzhx/ag_news your-username/ag-news-setfit \
           --num-samples 8
    @@ -363,13 +428,15 @@

    For agents

    const button = event.target; const pre = button.previousElementSibling; const done = () => { button.textContent = 'Copied'; setTimeout(() => { button.textContent = 'Copy'; }, 1400); }; - navigator.clipboard.writeText(pre.textContent).then(done).catch(() => { + const selectText = () => { const range = document.createRange(); range.selectNodeContents(pre); getSelection().removeAllRanges(); getSelection().addRange(range); button.textContent = 'Selected'; - }); + }; + if (!navigator.clipboard) { selectText(); return; } + navigator.clipboard.writeText(pre.textContent).then(done).catch(selectText); }); diff --git a/run-on-jobs/recipes.json b/run-on-jobs/recipes.json index 144b42d..deaa39d 100644 --- a/run-on-jobs/recipes.json +++ b/run-on-jobs/recipes.json @@ -12,7 +12,7 @@ "source": "header", "flavor": "l4x1", "timeout": "1h", - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/classification/raw/main/classify-dataset-sglang.py \\\n --input-dataset INPUT_DATASET --column COLUMN --labels LABELS --output-dataset OUTPUT_DATASET", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/classification/raw/main/classify-dataset-sglang.py \\\n --input-dataset your-username/emails \\\n --column content \\\n --labels \"spam,ham\" \\\n --output-dataset your-username/emails-classified \\\n --reasoning", "summary": "Classify text columns in Hugging Face datasets using SGLang with reasoning-aware models.", "declared": true }, @@ -28,7 +28,7 @@ "source": "header", "flavor": "l4x1", "timeout": "1h", - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/classification/raw/main/classify-dataset.py \\\n --input-dataset INPUT_DATASET --column COLUMN --labels LABELS --output-dataset OUTPUT_DATASET", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/classification/raw/main/classify-dataset.py \\\n --input-dataset your-username/emails \\\n --column content \\\n --labels \"spam,ham\" \\\n --output-dataset your-username/emails-classified \\\n --enable-reasoning", "summary": "Classify text columns in Hugging Face datasets using vLLM with structured outputs.", "declared": true }, @@ -44,7 +44,7 @@ "source": "header", "flavor": "t4-small", "timeout": "1h", - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/classification/raw/main/classify-gliner2.py \\\n INPUT_DATASET OUTPUT_DATASET", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/classification/raw/main/classify-gliner2.py \\\n fancyzhx/ag_news your-username/ag-news-gliner2 \\\n --labels World Sports Business \"Science and technology\" --max-samples 1000", "summary": "Classify a text column of a Hub dataset with GLiNER2 — zero-shot, or with your fine-tuned model.", "declared": true }, @@ -60,7 +60,7 @@ "source": "header", "flavor": "l4x1", "timeout": "1h", - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-classifier.py \\\n INPUT_DATASET OUTPUT_REPO", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-classifier.py \\\n fancyzhx/ag_news your-username/my-news-classifier \\\n --max-samples 2000 --epochs 1", "summary": "Fine-tune a text-classification encoder on a Hub dataset and push the trained model to the Hub.", "declared": false }, @@ -76,7 +76,7 @@ "source": "header", "flavor": "t4-small", "timeout": "1h", - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-gliner2.py \\\n INPUT_DATASET OUTPUT_REPO", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-gliner2.py \\\n biglam/blbooksgenre your-username/gliner2-blbooks-genre \\\n --dataset-config title_genre_classifiction --text-column title", "summary": "Fine-tune GLiNER2 into a text classifier — a small model (74M to 287M parameters, depending on the base checkpoint) that already works zero-shot.", "declared": false }, @@ -92,7 +92,7 @@ "source": "documented", "flavor": null, "timeout": null, - "command": "hf jobs uv run --flavor cpu-basic --secrets HF_TOKEN \\\n https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-setfit.py \\\n fancyzhx/ag_news username/ag-news-setfit \\\n --num-samples 8", + "command": "hf jobs uv run --flavor cpu-basic --secrets HF_TOKEN \\\n https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-setfit.py \\\n fancyzhx/ag_news your-username/ag-news-setfit \\\n --num-samples 8", "summary": "Few-shot text classification with SetFit — train on 8-64 labelled examples per class, on CPU or GPU.", "declared": false }, @@ -108,7 +108,7 @@ "source": "documented", "flavor": null, "timeout": null, - "command": "hf jobs uv run --flavor l4x1 -s HF_TOKEN https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/embed-to-lance.py \\\n stanfordnlp/imdb your-name/imdb-vecdb --column text --model BAAI/bge-base-en-v1.5 --private", + "command": "hf jobs uv run --flavor l4x1 -s HF_TOKEN \\\n https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/embed-to-lance.py \\\n stanfordnlp/imdb your-username/imdb-vecdb --column text --model BAAI/bge-base-en-v1.5 --private", "summary": "Embed a Hugging Face dataset and push it back as a Lance vector index — a Hub dataset that IS a searchable vector database.", "declared": false }, @@ -124,8 +124,8 @@ "source": "documented", "flavor": null, "timeout": null, - "command": "hf jobs uv run --flavor l4x1 -s HF_TOKEN https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/generate-embeddings-vllm.py \\\n stanfordnlp/imdb your-name/imdb-embeddings --column text --model Qwen/Qwen3-Embedding-0.6B --private", - "summary": "High-throughput embedding generation with vLLM pooling mode — the \"scale\" variant of generate-embeddings.py, for large *decoder* embedding models (e.g", + "command": "hf jobs uv run --flavor l4x1 -s HF_TOKEN \\\n https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/generate-embeddings-vllm.py \\\n stanfordnlp/imdb your-username/imdb-embeddings --column text --model Qwen/Qwen3-Embedding-0.6B --private", + "summary": "High-throughput embedding generation with vLLM pooling mode — the \"scale\" variant of generate-embeddings.py, for large decoder embedding models (e.g.", "declared": false }, { @@ -140,8 +140,8 @@ "source": "documented", "flavor": null, "timeout": null, - "command": "hf jobs uv run --flavor l4x1 -s HF_TOKEN https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/generate-embeddings.py \\\n stanfordnlp/imdb your-name/imdb-embeddings \\\n --column text --model sentence-transformers/all-MiniLM-L6-v2", - "summary": "Generate embeddings for a Hugging Face dataset (text OR images) with sentence-transformers, and push the result back to the Hub as a new dataset with ", + "command": "hf jobs uv run --flavor l4x1 -s HF_TOKEN \\\n https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/generate-embeddings.py \\\n stanfordnlp/imdb your-username/imdb-embeddings \\\n --column text --model sentence-transformers/all-MiniLM-L6-v2", + "summary": "Generate embeddings for a Hugging Face dataset (text OR images) with sentence-transformers, and push the result back to the Hub as a new dataset with…", "declared": true }, { @@ -172,7 +172,7 @@ "source": "header", "flavor": "a10g-small", "timeout": null, - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/deepseek-ocr-vllm.py \\\n INPUT_DATASET OUTPUT_DATASET", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/deepseek-ocr-vllm.py \\\n my-dataset my-output --max-samples 10", "summary": "Convert document images to markdown using DeepSeek-OCR with vLLM.", "declared": true }, @@ -188,7 +188,7 @@ "source": "header", "flavor": "a10g-small", "timeout": null, - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/deepseek-ocr2-vllm.py \\\n INPUT_DATASET OUTPUT_DATASET", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/deepseek-ocr2-vllm.py \\\n my-dataset my-output --max-samples 10", "summary": "Convert document images to markdown using DeepSeek-OCR-2 with vLLM.", "declared": true }, @@ -236,7 +236,7 @@ "source": "header", "flavor": "a10g-small", "timeout": null, - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/glm-ocr.py \\\n INPUT_DATASET OUTPUT_DATASET", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/glm-ocr.py \\\n {source_dataset} \\\n \\\n --image-column {image_column} \\\n --batch-size {batch_size} \\\n --task {task}", "summary": "Convert document images to markdown using GLM-OCR with vLLM.", "declared": true }, @@ -268,7 +268,7 @@ "source": "header", "flavor": "a100-large", "timeout": null, - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lift-extract.py \\\n INPUT_DATASET OUTPUT_DATASET --schema SCHEMA", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lift-extract.py \\\n INPUT_DATASET OUTPUT_DATASET \\\n --schema '{\"type\":\"object\",\"properties\":{\"title\":{\"type\":\"string\"}}}' \\\n --max-samples 5 --shuffle --seed 42", "summary": "Extract structured JSON from document images OR multi-page PDFs using Datalab's lift model (datalab-to/lift, 9B, Qwen3.5-based).", "declared": true }, @@ -284,7 +284,7 @@ "source": "header", "flavor": "a10g-small", "timeout": null, - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr2-saturate.py \\\n INPUT_DATASET OUTPUT_DATASET", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr2-saturate.py \\\n ", "summary": "Convert document images to markdown using LightOnOCR-2 via saturate.", "declared": true }, @@ -300,7 +300,7 @@ "source": "header", "flavor": "a10g-small", "timeout": null, - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr2.py \\\n INPUT_DATASET OUTPUT_DATASET", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr2.py \\\n ", "summary": "Convert document images to markdown using LightOnOCR-2 with vLLM.", "declared": true }, @@ -316,7 +316,7 @@ "source": "header", "flavor": "a10g-small", "timeout": null, - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr3-bucket.py \\\n INPUT OUTPUT", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr3-bucket.py \\\n hf://buckets/biglam/britannica/source/pages/00070476bsb \\\n hf://buckets/your-username/ocr-output/britannica --mode grounding --max-samples 20", "summary": "OCR images and PDFs from an HF Bucket (or a directory) using LightOnOCR-3, writing markdown files.", "declared": true }, @@ -332,7 +332,7 @@ "source": "header", "flavor": "a10g-small", "timeout": null, - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr3.py \\\n INPUT_DATASET OUTPUT_DATASET", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/lighton-ocr3.py \\\n INPUT_DATASET OUTPUT_DATASET --max-samples 10", "summary": "Convert document images to markdown (or layout blocks) using LightOnOCR-3 with vLLM.", "declared": true }, @@ -348,7 +348,7 @@ "source": "header", "flavor": "a10g-large", "timeout": "2h", - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/minicpm-ocr.py \\\n INPUT OUTPUT", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/minicpm-ocr.py \\\n INPUT_DATASET OUTPUT_DATASET --max-samples 20", "summary": "Convert document images to markdown with OpenBMB's MiniCPM-OCR 1.0 pipeline.", "declared": false }, @@ -364,7 +364,7 @@ "source": "header", "flavor": "a10g-small", "timeout": null, - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/nuextract3.py \\\n INPUT_DATASET OUTPUT_DATASET", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/nuextract3.py \\\n INPUT_DATASET OUTPUT_DATASET --max-samples 5 --shuffle --seed 42", "summary": "Convert document images to markdown OR extract structured JSON using NuExtract3 with vLLM.", "declared": true }, @@ -396,7 +396,7 @@ "source": "header", "flavor": "a10g-small", "timeout": null, - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/ovis-ocr2-saturate.py \\\n INPUT_DATASET OUTPUT_DATASET", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/ovis-ocr2-saturate.py \\\n ", "summary": "Convert document images to markdown using OvisOCR2 via saturate.", "declared": true }, @@ -412,7 +412,7 @@ "source": "header", "flavor": "a10g-small", "timeout": null, - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/ovis-ocr2.py \\\n INPUT_DATASET OUTPUT_DATASET", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/ovis-ocr2.py \\\n INPUT_DATASET OUTPUT_DATASET --batch-size 16", "summary": "Convert document images to markdown using OvisOCR2 with vLLM.", "declared": true }, @@ -444,7 +444,7 @@ "source": "header", "flavor": "a10g-small", "timeout": null, - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/qianfan-ocr.py \\\n INPUT_DATASET OUTPUT_DATASET", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/qianfan-ocr.py \\\n INPUT_DATASET OUTPUT_DATASET --max-samples 10", "summary": "Convert document images to markdown using Qianfan-OCR with vLLM.", "declared": true }, @@ -460,7 +460,7 @@ "source": "header", "flavor": "a10g-small", "timeout": null, - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/surya-ocr.py \\\n INPUT_DATASET OUTPUT_DATASET", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/surya-ocr.py \\\n INPUT_DATASET OUTPUT_DATASET \\\n --max-samples 5 --shuffle --seed 42", "summary": "Document intelligence on images OR multi-page PDFs with Datalab's Surya OCR 2 (datalab-to/surya-ocr-2, 650M, Qwen3.5-style).", "declared": true }, @@ -476,7 +476,7 @@ "source": "header", "flavor": "a10g-small", "timeout": null, - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr-vllm.py \\\n INPUT_DATASET OUTPUT_DATASET", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr-vllm.py \\\n your-input-dataset your-output-dataset --max-samples 10", "summary": "Convert document images to markdown using Baidu Unlimited-OCR with vLLM.", "declared": true }, @@ -492,7 +492,7 @@ "source": "header", "flavor": "rtx-pro-6000", "timeout": "4h", - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr2-live.py \\\n INPUT OUTPUT", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr2-live.py \\\n \"hf://buckets/biglam/britannica/source/pages/1771EncyclopediaBritannicaNLS/*.jp2\" \\\n /britannica-1771 --live-port 7860", "summary": "unlimited-ocr2.py with a live view you can watch (and screen-record) while the Job runs.", "declared": false }, @@ -508,7 +508,7 @@ "source": "header", "flavor": "rtx-pro-6000", "timeout": "4h", - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr2-saturate.py \\\n INPUT OUTPUT", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr2-saturate.py \\\n \"hf://buckets/biglam/britannica/source/pages/1771EncyclopediaBritannicaNLS/*.jp2\" \\\n /britannica-1771-uocr2", "summary": "OCR whole documents (book volumes, PDFs) with Baidu Unlimited-OCR-2 via saturate.", "declared": false }, @@ -524,7 +524,7 @@ "source": "header", "flavor": "rtx-pro-6000", "timeout": "4h", - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr2.py \\\n INPUT OUTPUT", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/ocr/raw/main/unlimited-ocr2.py \\\n \"hf://buckets/biglam/britannica/source/pages/1771EncyclopediaBritannicaNLS/*.jp2\" \\\n /britannica-1771", "summary": "OCR whole documents (book volumes, folders of scans) with Baidu Unlimited-OCR-2.", "declared": true }, @@ -540,7 +540,7 @@ "source": "documented", "flavor": null, "timeout": null, - "command": "hf jobs uv run --flavor a100-large \\\n -s HF_TOKEN \\\n https://huggingface.co/datasets/uv-scripts/sam3/raw/main/detect-objects.py \\\n input-dataset output-dataset \\\n --class-name photograph \\\n --confidence-threshold 0.5", + "command": "hf jobs uv run --flavor a100-large \\\n -s HF_TOKEN \\\n https://huggingface.co/datasets/uv-scripts/sam3/raw/main/detect-objects.py \\\n INPUT_DATASET OUTPUT_DATASET \\\n --class-name photograph \\\n --confidence-threshold 0.5", "summary": "Detect objects in images using Meta's SAM3 (Segment Anything Model 3).", "declared": true }, @@ -556,7 +556,7 @@ "source": "documented", "flavor": null, "timeout": null, - "command": "hf jobs uv run --flavor a100-large \\\n -s HF_TOKEN \\\n https://huggingface.co/datasets/uv-scripts/sam3/raw/main/segment-objects.py \\\n input-dataset output-dataset \\\n --class-name photograph", + "command": "hf jobs uv run --flavor a100-large \\\n -s HF_TOKEN \\\n https://huggingface.co/datasets/uv-scripts/sam3/raw/main/segment-objects.py \\\n INPUT_DATASET OUTPUT_DATASET \\\n --class-name photograph", "summary": "Segment objects in images using Meta's SAM3 (Segment Anything Model 3).", "declared": true }, @@ -585,10 +585,10 @@ "CohereLabs/cohere-transcribe-03-2026" ], "support": null, - "source": "flags-needed", + "source": "documented", "flavor": null, "timeout": null, - "command": null, + "command": "hf jobs uv run --flavor l4x1 \\\n -s HF_TOKEN \\\n -v hf://buckets/your-username/audio-input:/input:ro \\\n -v hf://buckets/your-username/transcripts:/output \\\n https://huggingface.co/datasets/uv-scripts/transcription/raw/main/cohere-transcribe.py \\\n /input /output --language en --compile", "summary": "Transcribe audio files from a directory using Cohere Transcribe via transformers.", "declared": false }, @@ -603,10 +603,10 @@ "facebook/mms-1b-all" ], "support": null, - "source": "flags-needed", + "source": "documented", "flavor": null, "timeout": null, - "command": null, + "command": "hf jobs uv run --flavor l4x1 -s HF_TOKEN \\\n -e UV_TORCH_BACKEND=cu128 \\\n -v hf://buckets/your-username/audio-files:/input:ro \\\n -v hf://buckets/your-username/transcripts-aligned:/output \\\n https://huggingface.co/datasets/uv-scripts/transcription/raw/main/easytranscriber-transcribe.py \\\n /input /output \\\n --language en --emit-txt --emit-srt", "summary": "Transcribe audio with word-level timestamps using kb-labb/easytranscriber.", "declared": false }, @@ -619,10 +619,10 @@ "ibm-granite/granite-speech-5.0-470m-turboctc" ], "support": null, - "source": "flags-needed", + "source": "documented", "flavor": null, "timeout": null, - "command": null, + "command": "hf jobs uv run --flavor l4x1 -s HF_TOKEN \\\n -e UV_TORCH_BACKEND=cu128 \\\n -v hf://buckets/your-username/audio-input:/input:ro \\\n -v hf://buckets/your-username/transcripts:/output \\\n https://huggingface.co/datasets/uv-scripts/transcription/raw/main/granite-turboctc-transcribe.py \\\n /input /output", "summary": "Transcribe English audio files with IBM Granite Speech 5.0 TurboCTC (470M).", "declared": false }, @@ -651,10 +651,10 @@ "OpenMOSS-Team/MOSS-Transcribe-Diarize" ], "support": null, - "source": "flags-needed", + "source": "documented", "flavor": null, "timeout": null, - "command": null, + "command": "hf jobs uv run --flavor l4x1 -s HF_TOKEN \\\n -e UV_TORCH_BACKEND=cu128 \\\n -v hf://buckets/your-username/audio-files:/input:ro \\\n -v hf://buckets/your-username/transcripts:/output \\\n https://huggingface.co/datasets/uv-scripts/transcription/raw/main/moss-transcribe-diarize.py \\\n /input /output --emit-txt --emit-srt", "summary": "Transcribe + diarize audio files using MOSS-Transcribe-Diarize (0.9B).", "declared": false }, @@ -670,7 +670,7 @@ "source": "header", "flavor": "rtx-pro-6000", "timeout": null, - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/transcription/raw/main/nemotron-transcribe.py \\\n INPUT_DIR OUTPUT_DIR", + "command": "hf jobs uv run \\\n -v hf://buckets/your-username/audio-files:/input:ro \\\n -v hf://buckets/your-username/transcripts:/output \\\n https://huggingface.co/datasets/uv-scripts/transcription/raw/main/nemotron-transcribe.py \\\n /input /output", "summary": "Transcribe audio with NVIDIA Nemotron 3.5 Transcribe via an in-job vLLM server.", "declared": true }, @@ -686,7 +686,7 @@ "source": "header", "flavor": "a10g-small", "timeout": "2h", - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/video/raw/main/marlin-caption.py \\\n INPUT_DIR OUTPUT", + "command": "hf jobs uv run \\\n -v hf://buckets/your-username/my-videos:/input:ro \\\n https://huggingface.co/datasets/uv-scripts/video/raw/main/marlin-caption.py \\\n /input hf://buckets/your-username/my-videos/captions", "summary": "Caption videos with timestamped events using Marlin-2B, writing a resumable dataset.", "declared": true }, @@ -702,7 +702,7 @@ "source": "header", "flavor": "a100-large", "timeout": null, - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/video/raw/main/qwen38-caption.py \\\n INPUT_DIR OUTPUT", + "command": "hf jobs uv run \\\n -v hf://buckets/your-username/my-videos:/input:ro \\\n https://huggingface.co/datasets/uv-scripts/video/raw/main/qwen38-caption.py \\\n /input hf://buckets/your-username/my-videos/captions", "summary": "Caption whole videos — no chunking — with Qwen3.8-27B, writing a resumable dataset.", "declared": true }, @@ -718,7 +718,7 @@ "source": "header", "flavor": "a100-large", "timeout": "2h", - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/vllm/raw/main/generate-responses.py \\\n SRC_DATASET_HUB_ID OUTPUT_DATASET_HUB_ID", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/vllm/raw/main/generate-responses.py \\\n input output --max-model-len 32768", "summary": "Generate responses for prompts in a dataset using vLLM for efficient GPU inference.", "declared": false }, @@ -734,7 +734,7 @@ "source": "header", "flavor": "l40sx1", "timeout": "1h", - "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/vllm/raw/main/vlm-classify.py \\\n INPUT_DATASET OUTPUT_DATASET --classes CLASSES", + "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/vllm/raw/main/vlm-classify.py \\\n your-username/INPUT_DATASET \\\n your-username/OUTPUT_DATASET \\\n --classes \"title-page,content,index,other\"", "summary": "Classify images using Vision Language Models with vLLM.", "declared": true }, @@ -751,7 +751,7 @@ "flavor": "a100-large", "timeout": "1h", "command": "hf jobs uv run \\\n https://huggingface.co/datasets/uv-scripts/vlm-object-detection/raw/main/qwen3vl-detect-fewshot.py \\\n INPUT_DATASET OUTPUT_DATASET", - "summary": "[FEW-SHOT VARIANT] Instruction-oriented object detection with Qwen3-VL via vLLM.", + "summary": "Instruction-oriented object detection with Qwen3-VL via vLLM.", "declared": true }, { diff --git a/tools/build-catalog.py b/tools/build-catalog.py index 5665f46..f588c56 100755 --- a/tools/build-catalog.py +++ b/tools/build-catalog.py @@ -69,11 +69,12 @@ OCR_SUPPORT_LEVELS = {"core", "experimental"} SKIP_SCRIPT = re.compile(r"(^_|^test_|conftest|setup|benchmark|judge|compare)", re.IGNORECASE) ALTERNATIVE_SCRIPT = re.compile(r"saturate|live|server|fleet|fewshot", re.IGNORECASE) +PATH_ARGUMENT = re.compile(r"^(input|output)$|_dir$|_path$|_folder$") MODEL_ID = re.compile(r"^[A-Za-z0-9][\w.-]*/[\w.+-]+$") PLACEHOLDER_OWNERS = {"org", "datasets", "models", "hf", "bucket", "buckets", "input", "output", "user", "your", "username", "path", "dir", "my-org", "uv-scripts"} -STATUS = {"header": "ready to run", "documented": "example from the script", "flags-needed": "set options first"} -ROW_STATUS = {"header": "ready", "documented": "example", "flags-needed": "options needed"} +STATUS = {"header": "command ready", "documented": "example command", "flags-needed": "read the script first"} +ROW_STATUS = {"header": "command ready", "documented": "example command", "flags-needed": "no command yet"} def read_header(text): @@ -128,31 +129,66 @@ def find_models(constants, arguments): def first_documented_command(text, script_name, url): - match = re.search(r"hf jobs uv run(?:[^\n]*\\\n)*[^\n]*", text) - if not match or script_name not in match.group(0): - return None - lines = [re.sub(r"^\s*(#\s*)?", "", line).rstrip(" \\") for line in match.group(0).split("\n")] - command = " \\\n ".join(line for line in lines if line) - if url not in command: - command = re.sub(r"(?{html.escape(recipe["summary"])}

    ' if recipe["summary"] else "" if recipe["source"] == "flags-needed": - body = f'

    Read the script for its options. It has no launch settings yet.

    ' + body = f'

    Read the script for its options. There is no ready-made command yet.

    ' else: body = command_block(recipe["command"]) name = recipe["script"].split("/")[-1] @@ -302,7 +339,7 @@ def render_readme(recipes): colorTo: gray sdk: static pinned: false -short_description: Run this model over your own data on HF Jobs +short_description: Batch-run this model on your own data with HF Jobs models: {model_lines} --- @@ -324,7 +361,7 @@ def render_agents(): - Check `hf version` (needs 1.32+). If it's missing: `curl -LsSf https://hf.co/cli/install.sh | bash`, then `hf auth login`. - Jobs need pay-as-you-go credit, and each job costs money. Confirm with the user before starting one. -- The CLI is the current reference: `hf --help`, `hf jobs uv run --help`, `hf jobs hardware`. For a skill, use `hf skills add`. +- The CLI is the current reference: `hf --help`, `hf jobs uv run --help`, `hf jobs hardware`. To install the Hugging Face CLI skill, run `hf skills add`. ## Find a recipe @@ -336,7 +373,7 @@ def render_agents(): ## Run it -Most recipes go from dataset to dataset: +Start from the recipe's `command` field. Most recipes go from dataset to dataset: hf jobs uv run --max-samples 10 diff --git a/tools/run-on-jobs-template.html b/tools/run-on-jobs-template.html index ee41626..fcf097e 100644 --- a/tools/run-on-jobs-template.html +++ b/tools/run-on-jobs-template.html @@ -77,15 +77,16 @@ body .more{margin-left:16px} +@media (prefers-reduced-motion:reduce){summary::before{transition:none}}

    Use Hub models on your own data

    -

    Run a model over your whole dataset, or fine-tune it on your own examples. One command starts a GPU on Hugging Face Jobs and saves the results to the Hub. There is nothing to clone.

    +

    Run a model over your whole dataset, or fine-tune it on your own examples. Each command starts a paid batch job on Hugging Face Jobs and saves the results to the Hub. There is nothing to clone.

    -

    Read seven scanned NASA pages with GLM-OCR and save the text to a new dataset on your account.

    hf jobs uv run \
    +

    Read seven scanned NASA pages with GLM-OCR and save the text to a new public dataset on your account. Add --private to keep it private.

    hf jobs uv run \
         https://huggingface.co/datasets/uv-scripts/ocr/raw/main/glm-ocr.py \
         uv-scripts/ocr-demo your-username/ocr-demo-results
    The scan
    Scanned page listing Space Shuttle foods
    What the Job wrote
    Space Shuttle Food and Beverage List
     
    @@ -225,7 +226,7 @@ 

    Use Hub models on your own data

    You need the hf CLI (1.32 or newer), a login and pay-as-you-go credit. Add --dry-run to see the GPU and settings without starting a job.

    Find your model

    -

    In the commands, INPUT and OUTPUT are dataset IDs unless the recipe says otherwise.

    +

    Replace the capitalised placeholders and your-username. Check the script if you're unsure what a value should be.

    @@ -277,13 +278,15 @@

    For agents

    const button = event.target; const pre = button.previousElementSibling; const done = () => { button.textContent = 'Copied'; setTimeout(() => { button.textContent = 'Copy'; }, 1400); }; - navigator.clipboard.writeText(pre.textContent).then(done).catch(() => { + const selectText = () => { const range = document.createRange(); range.selectNodeContents(pre); getSelection().removeAllRanges(); getSelection().addRange(range); button.textContent = 'Selected'; - }); + }; + if (!navigator.clipboard) { selectText(); return; } + navigator.clipboard.writeText(pre.textContent).then(done).catch(selectText); }); From afe984daadaf478f6bea5288b2758d9d2ba88872 Mon Sep 17 00:00:00 2001 From: Daniel van Strien Date: Fri, 30 Oct 2026 14:04:01 +0000 Subject: [PATCH 08/10] run-on-jobs: simplify the intro Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_016isSPpM5PRqNUzwsDntoG4 --- run-on-jobs/index.html | 2 +- tools/run-on-jobs-template.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/run-on-jobs/index.html b/run-on-jobs/index.html index e8c535d..bbfbe9b 100644 --- a/run-on-jobs/index.html +++ b/run-on-jobs/index.html @@ -83,7 +83,7 @@

    Use Hub models on your own data

    -

    Run a model over your whole dataset, or fine-tune it on your own examples. Each command starts a paid batch job on Hugging Face Jobs and saves the results to the Hub. There is nothing to clone.

    +

    Run a model over your whole dataset, or fine-tune it on your own examples. Each command starts a job on Hugging Face Jobs and saves the results to the Hub. There is nothing to clone.

    Read seven scanned NASA pages with GLM-OCR and save the text to a new public dataset on your account. Add --private to keep it private.

    hf jobs uv run \
    diff --git a/tools/run-on-jobs-template.html b/tools/run-on-jobs-template.html
    index fcf097e..da60e96 100644
    --- a/tools/run-on-jobs-template.html
    +++ b/tools/run-on-jobs-template.html
    @@ -83,7 +83,7 @@
     
     

    Use Hub models on your own data

    -

    Run a model over your whole dataset, or fine-tune it on your own examples. Each command starts a paid batch job on Hugging Face Jobs and saves the results to the Hub. There is nothing to clone.

    +

    Run a model over your whole dataset, or fine-tune it on your own examples. Each command starts a job on Hugging Face Jobs and saves the results to the Hub. There is nothing to clone.

    Read seven scanned NASA pages with GLM-OCR and save the text to a new public dataset on your account. Add --private to keep it private.

    hf jobs uv run \
    
    From a42a92080e403bf8fdc7d06f061f2b891b29b5cc Mon Sep 17 00:00:00 2001
    From: Daniel van Strien 
    Date: Fri, 30 Oct 2026 14:04:21 +0000
    Subject: [PATCH 09/10] run-on-jobs: keep inline code on one line
    
    Co-Authored-By: Claude Opus 5.5 
    Claude-Session: https://claude.ai/code/session_016isSPpM5PRqNUzwsDntoG4
    ---
     run-on-jobs/index.html          | 2 +-
     tools/run-on-jobs-template.html | 2 +-
     2 files changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/run-on-jobs/index.html b/run-on-jobs/index.html
    index bbfbe9b..b194797 100644
    --- a/run-on-jobs/index.html
    +++ b/run-on-jobs/index.html
    @@ -21,7 +21,7 @@
     .muted{color:var(--muted)}
     .small{font-size:14.5px}
     code,pre,input,summary{font-family:var(--mono)}
    -code{font-size:.86em}
    +code{font-size:.86em;white-space:nowrap}
     pre{font-size:12.5px;line-height:1.55;margin:0;padding:10px 12px;background:var(--code);border-radius:4px;white-space:pre;overflow-x:auto;min-width:0}
     .cmd{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px;align-items:start;margin:6px 0 8px;min-width:0}
     .copy{font:500 12px var(--text);padding:3px 8px;background:var(--bg);color:var(--fg);border:1px solid var(--rule);border-radius:4px;cursor:pointer}
    diff --git a/tools/run-on-jobs-template.html b/tools/run-on-jobs-template.html
    index da60e96..d03f679 100644
    --- a/tools/run-on-jobs-template.html
    +++ b/tools/run-on-jobs-template.html
    @@ -21,7 +21,7 @@
     .muted{color:var(--muted)}
     .small{font-size:14.5px}
     code,pre,input,summary{font-family:var(--mono)}
    -code{font-size:.86em}
    +code{font-size:.86em;white-space:nowrap}
     pre{font-size:12.5px;line-height:1.55;margin:0;padding:10px 12px;background:var(--code);border-radius:4px;white-space:pre;overflow-x:auto;min-width:0}
     .cmd{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px;align-items:start;margin:6px 0 8px;min-width:0}
     .copy{font:500 12px var(--text);padding:3px 8px;background:var(--bg);color:var(--fg);border:1px solid var(--rule);border-radius:4px;cursor:pointer}
    
    From cffc81473624fbad2ba8b74e3c5fd61d85fce05d Mon Sep 17 00:00:00 2001
    From: Daniel van Strien 
    Date: Fri, 30 Oct 2026 14:08:50 +0000
    Subject: [PATCH 10/10] run-on-jobs: add a SetFit fine-tuning example and skill
     pointers
    
    Co-Authored-By: Claude Opus 5.5 
    Claude-Session: https://claude.ai/code/session_016isSPpM5PRqNUzwsDntoG4
    ---
     run-on-jobs/AGENTS.md           | 1 +
     run-on-jobs/index.html          | 7 ++++++-
     tools/build-catalog.py          | 1 +
     tools/run-on-jobs-template.html | 7 ++++++-
     4 files changed, 14 insertions(+), 2 deletions(-)
    
    diff --git a/run-on-jobs/AGENTS.md b/run-on-jobs/AGENTS.md
    index da29bcd..5d73744 100644
    --- a/run-on-jobs/AGENTS.md
    +++ b/run-on-jobs/AGENTS.md
    @@ -15,6 +15,7 @@ Each recipe is one script, run from its URL with `hf jobs uv run`. There is noth
     - `source`: `header` carries its launch settings; `documented` is an example from the script's docs; `flags-needed` has no command, so read the script first.
     - Read a script's docstring and options: `curl -s  | head -100`. Running it locally may fail on GPU-only dependencies.
     - Each task's README explains its recipes, for example https://huggingface.co/datasets/uv-scripts/ocr. OCR also has `models.json`, with language coverage and support levels.
    +- Fuller guides: [uv-recipes](https://github.com/davanstrien/uv-scripts/tree/main/skills/uv-recipes) and, for few-shot fine-tuning, [setfit-on-jobs](https://github.com/davanstrien/uv-scripts/tree/main/skills/setfit-on-jobs).
     
     ## Run it
     
    diff --git a/run-on-jobs/index.html b/run-on-jobs/index.html
    index b194797..2c955ea 100644
    --- a/run-on-jobs/index.html
    +++ b/run-on-jobs/index.html
    @@ -85,7 +85,7 @@
     

    Use Hub models on your own data

    Run a model over your whole dataset, or fine-tune it on your own examples. Each command starts a job on Hugging Face Jobs and saves the results to the Hub. There is nothing to clone.

    -
    +

    Read seven scanned NASA pages with GLM-OCR and save the text to a new public dataset on your account. Add --private to keep it private.

    hf jobs uv run \
         https://huggingface.co/datasets/uv-scripts/ocr/raw/main/glm-ocr.py \
         uv-scripts/ocr-demo your-username/ocr-demo-results
    The scan
    Scanned page listing Space Shuttle foods
    What the Job wrote
    Space Shuttle Food and Beverage List
    @@ -223,6 +223,11 @@ 

    Use Hub models on your own data

    https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/generate-embeddings.py \ stanfordnlp/imdb your-username/imdb-embeddings \ --column text --max-samples 100 --private

    One L4 GPU embeds about 900 rows per second with all-MiniLM-L6-v2.

    +

    Train a news topic classifier from 16 examples, with no GPU, and save the model to your account.

    hf jobs uv run --flavor cpu-basic --secrets HF_TOKEN \
    +    https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-setfit.py \
    +    fancyzhx/ag_news your-username/ag-news-setfit \
    +    --num-samples 4 --max-train-pool 2000 --max-eval-samples 100 \
    +    --max-seq-length 128 --sampling-strategy undersampling --max-minutes 5

    Our run: 0.77 accuracy on 100 test articles, against 0.32 for always guessing the most common topic. Training took 20 seconds on cpu-basic.

    You need the hf CLI (1.32 or newer), a login and pay-as-you-go credit. Add --dry-run to see the GPU and settings without starting a job.

    Find your model

    diff --git a/tools/build-catalog.py b/tools/build-catalog.py index f588c56..a387360 100755 --- a/tools/build-catalog.py +++ b/tools/build-catalog.py @@ -370,6 +370,7 @@ def render_agents(): - `source`: `header` carries its launch settings; `documented` is an example from the script's docs; `flags-needed` has no command, so read the script first. - Read a script's docstring and options: `curl -s | head -100`. Running it locally may fail on GPU-only dependencies. - Each task's README explains its recipes, for example https://huggingface.co/datasets/uv-scripts/ocr. OCR also has `models.json`, with language coverage and support levels. +- Fuller guides: [uv-recipes](https://github.com/davanstrien/uv-scripts/tree/main/skills/uv-recipes) and, for few-shot fine-tuning, [setfit-on-jobs](https://github.com/davanstrien/uv-scripts/tree/main/skills/setfit-on-jobs). ## Run it diff --git a/tools/run-on-jobs-template.html b/tools/run-on-jobs-template.html index d03f679..5fee821 100644 --- a/tools/run-on-jobs-template.html +++ b/tools/run-on-jobs-template.html @@ -85,7 +85,7 @@

    Use Hub models on your own data

    Run a model over your whole dataset, or fine-tune it on your own examples. Each command starts a job on Hugging Face Jobs and saves the results to the Hub. There is nothing to clone.

    -
    +

    Read seven scanned NASA pages with GLM-OCR and save the text to a new public dataset on your account. Add --private to keep it private.

    hf jobs uv run \
         https://huggingface.co/datasets/uv-scripts/ocr/raw/main/glm-ocr.py \
         uv-scripts/ocr-demo your-username/ocr-demo-results
    The scan
    Scanned page listing Space Shuttle foods
    What the Job wrote
    Space Shuttle Food and Beverage List
    @@ -223,6 +223,11 @@ 

    Use Hub models on your own data

    https://huggingface.co/datasets/uv-scripts/embeddings/raw/main/generate-embeddings.py \ stanfordnlp/imdb your-username/imdb-embeddings \ --column text --max-samples 100 --private

    One L4 GPU embeds about 900 rows per second with all-MiniLM-L6-v2.

    +

    Train a news topic classifier from 16 examples, with no GPU, and save the model to your account.

    hf jobs uv run --flavor cpu-basic --secrets HF_TOKEN \
    +    https://huggingface.co/datasets/uv-scripts/classification/raw/main/train-setfit.py \
    +    fancyzhx/ag_news your-username/ag-news-setfit \
    +    --num-samples 4 --max-train-pool 2000 --max-eval-samples 100 \
    +    --max-seq-length 128 --sampling-strategy undersampling --max-minutes 5

    Our run: 0.77 accuracy on 100 test articles, against 0.32 for always guessing the most common topic. Training took 20 seconds on cpu-basic.

    You need the hf CLI (1.32 or newer), a login and pay-as-you-go credit. Add --dry-run to see the GPU and settings without starting a job.

    Find your model