Skip to content

feat: add vLLM batch inference and text-to-image batch job bundles - #2

Open
anika-suman-amazon wants to merge 16 commits into
mainlinefrom
batch-inference-jobs
Open

feat: add vLLM batch inference and text-to-image batch job bundles#2
anika-suman-amazon wants to merge 16 commits into
mainlinefrom
batch-inference-jobs

Conversation

@anika-suman-amazon

Copy link
Copy Markdown
Owner

What was the problem/requirement? (What/Why)

AWS Deadline Cloud had no sample job bundles for GPU-based AI batch workloads — specifically batch LLM inference and batch image generation. Users building pipelines around large language models or diffusion models had no reference for how to structure an OpenJD job that loads a model once per worker and distributes prompt tasks across a fleet efficiently.

What was the solution? (How)

Two new job bundles:

job_bundles/vllm_batch — Batch LLM inference using vLLM. A step environment starts a vLLM OpenAI-compatible server on each worker (loading the model once), and each task sends a single HTTP request to that server. An Aggregate step collects per-task results into a combined output.jsonl and results.html viewer. Default model: Qwen/Qwen2.5-7B-Instruct.

job_bundles/text_to_image_batch — Batch image generation using diffusers. A step environment loads a diffusion pipeline once per worker (via a tiny stdlib HTTP server), and each task POSTs a prompt and receives PNG bytes back. Optionally composites caption text over the image via PIL with auto-vibe font selection. An Aggregate step produces gallery.html. Default model: black-forest-labs/FLUX.2-klein-4B (Apache 2.0, no auth required, 4-step distilled, ~13 GB VRAM).

The two bundles are designed to chain: vllm_batch generates slogans or captions → text_to_image_batch renders them as images with the generated text overlaid as crisp typography. Both bundles include sample_prompts.jsonl, scripts/run_task.py, scripts/aggregate.py, and tools/prompt_builder.html (a zero-dependency browser tool for building JSONL input files).

What is the impact of this change?

Users get two ready-to-submit samples for GPU AI workloads:

  • vllm_batch demonstrates the "load model once, serve many tasks" pattern for LLM inference at scale on Deadline Cloud.
  • text_to_image_batch demonstrates the same pattern for diffusion-based image generation, and doubles as a standalone batch image generator or a downstream stage in a vLLM → image pipeline.

How was this change tested?

Both bundles were submitted to a live Deadline Cloud farm with an SMF fleet with NVIDIA GPUs and a Conda queue environment configured.

vllm_batch — submitted with sample_prompts.jsonl and Prompts=1-10, model Qwen/Qwen2.5-7B-Instruct. Verified that:

  • The vLLM server started and was polled ready before tasks began
  • Each task completed and wrote a per-task result_N.jsonl
  • The Aggregate step combined results into output.jsonl and results.html

text_to_image_batch — submitted with sample_prompts.jsonl (bakery slogans from vllm_batch output) and Prompts=1-8, model black-forest-labs/FLUX.2-klein-4B. Verified that:

  • The diffusers server loaded the pipeline and came up healthy before tasks began
  • Each task generated a PNG with caption overlay composited via PIL
  • The Aggregate step produced gallery.html with thumbnails, metadata, and search
  • Also works independently as a job bundle to produce images with optional captions in batch

The chain was also tested end-to-end: vllm_batch output.jsonl fed directly into text_to_image_batch as InputFile, with generated_text auto-detected as the overlay caption.

Was this change documented?

Yes. Both bundles include a README.md covering:

  • How it works (ASCII architecture diagram)
  • Farm setup prerequisites
  • Quick start (GUI and CLI submitter)
  • Prompt Range syntax
  • Input/output format
  • All parameters with defaults and descriptions
  • Chaining instructions (vllm_batchtext_to_image_batch)
  • Troubleshooting section

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

crowecawcaw and others added 2 commits June 25, 2026 15:23
…eadline#245)

Add a job bundle that renders an animated turntable in Blender, encodes a
review-ready movie, extracts a poster-frame thumbnail, and publishes the
result to Autodesk Flow Production Tracking (formerly ShotGrid) as a new
Version on an Asset's review Task.

The sample demonstrates two Deadline Cloud patterns:
- post-render work modeled as discrete OpenJD steps with step dependencies
  (encode and thumbnail fan out in parallel, then publish), and
- filling Flow job parameters from studio environment variables via a
  preSubmission hook, so the submitter does not enter them by hand.

Flow credentials are read at runtime from AWS Secrets Manager using the
worker's queue role.

Signed-off-by: Stephen Crowe <6042774+crowecawcaw@users.noreply.github.com>
Two new GPU job bundles for batch AI workloads on Deadline Cloud:

- job_bundles/vllm_batch: runs batch LLM inference using vLLM; loads the
  model once per worker via a step environment that starts a vLLM OpenAI-
  compatible server, then distributes prompt tasks across workers.

- job_bundles/text_to_image_batch: batch image generation using diffusers
  (default: FLUX.2 Klein 4B, Apache 2.0); loads the pipeline once per
  worker via a local HTTP server step environment. Supports caption overlay
  composited via PIL with auto font selection. Designed to chain from
  vllm_batch output.

Both bundles include a sample JSONL prompts file, run_task.py, aggregate.py,
and a browser-based prompt_builder.html tool.

Signed-off-by: Anika Suman <anika-suman-amazon@users.noreply.github.com>
Comment thread job_bundles/text_to_image_batch/scripts/run_task.py Fixed
Comment thread job_bundles/vllm_batch/scripts/run_task.py Fixed
Comment thread job_bundles/vllm_batch/scripts/run_task.py Fixed
Comment thread job_bundles/text_to_image_batch/template.yaml
Comment thread job_bundles/vllm_batch/template.yaml
Comment thread job_bundles/text_to_image_batch/scripts/aggregate.py
Comment thread job_bundles/vllm_batch/scripts/aggregate.py
Comment thread job_bundles/vllm_batch/template.yaml
Comment thread job_bundles/text_to_image_batch/scripts/run_task.py
anika-suman-amazon and others added 2 commits June 29, 2026 15:13
- Remove vllm_batch monkey-patch: pin prometheus-fastapi-instrumentator=8.0.2
  which fixes the _IncludedRouter AttributeError with FastAPI>=0.116, and
  switch start-vllm.sh to python -m vllm.entrypoints.openai.api_server directly
- Pin diffusers to a specific git commit in text_to_image_batch (Flux2KleinPipeline
  not yet in a PyPI release); document in README with upgrade instructions
- Escape less-than-slash in both aggregate.py HTML templates to prevent script tag injection
- Add explanatory comment to SLOGAN_REQUEST_PATTERN regex in run_task.py
- Add comment explaining --enforce-eager throughput trade-off in vllm_batch template
- Fix bare except to log warning in text_to_image_batch run_task.py
- Remove unused sys import and add explicit raise after retry loop in vllm_batch run_task.py

Signed-off-by: Anika Suman <anika-suman-amazon@users.noreply.github.com>
…s-deadline#246)

the published maya-openjd 0.14 requires maya >=2023,<2025, so the
environment solve fails for any consumer on the public deadline-cloud +
conda-forge channels. maya-openjd 0.15 is the released version with Maya
2025 support; bumping the pin makes the existing maya=2025 default solve
and render. Verified end-to-end on a service-managed Linux fleet
(1 frame, 2x2 tiles, all tasks SUCCEEDED).

Signed-off-by: Phillip Krasnick <259470369+phil-IO-p@users.noreply.github.com>
yuanmich2 and others added 12 commits July 1, 2026 17:29
…e V-Ray installer which was introducing bugs

Signed-off-by: Michael Yuan <160265179+yuanmich2@users.noreply.github.com>
…lent failures when renaming the V-Ray installer

Signed-off-by: Michael Yuan <160265179+yuanmich2@users.noreply.github.com>
Signed-off-by: Anika Suman <anika-suman-amazon@users.noreply.github.com>
…mport)

Signed-off-by: Anika Suman <anika-suman-amazon@users.noreply.github.com>
…mpty except

Signed-off-by: Anika Suman <anika-suman-amazon@users.noreply.github.com>
…ine#250)

- Update recipe to version 21.0.596 (build number 2, gcc11.2)
- Add zzz-houdini-plugin-sync-activate.sh to download plugins from S3
  and copy .json package descriptors to ~/houdini21.0/packages/
- Add zzz-houdini-plugin-sync-deactivate.sh for cleanup
- Update build.sh with HOUDINI_DONT_PURGE_* env vars and plugin sync
  script installation
- Update README with Plugin Sync usage documentation

Signed-off-by: Justin Sawatzky <132946620+justinsaws@users.noreply.github.com>
- Remove prometheus monkey-patch from vllm_launcher.py (private API)
- Replace O(N*M) per-prompt file reads with single-pass load_prompts()
- Add CSV formula injection mitigation to both aggregate scripts
- Add explicit return to satisfy CodeQL mixed-returns warning
- Add HfToken security note to vllm_batch README

Signed-off-by: Anika Suman <anika-suman-amazon@users.noreply.github.com>
Add samples for managing Python dependencies with pip, mirroring the
existing Conda samples:

- queue_environments/pip_queue_env.yaml: a queue environment that builds
  a Python virtual environment with venv and installs the PipPackages
  parameter into it, with optional PipIndexUrl/PipExtraIndexUrls for
  private indexes. No-ops when PipPackages is empty.
- job_bundles/pip_package_job: a job bundle that relies on the pip queue
  environment to provide its dependencies.
- job_bundles/pip_self_contained_job: a job bundle that manages its own
  pip virtual environment inline via a jobEnvironment, needing no queue
  environment.

The pip self-upgrade and package install both pass the index options so a
private PipIndexUrl works on workers that cannot reach public PyPI.

Both bundles were verified end-to-end on a Deadline Cloud service-managed
Linux fleet, and locally with the Open Job Description CLI.

Signed-off-by: Stephen Crowe <6042774+crowecawcaw@users.noreply.github.com>
…adline#252)

* ci: fix all high-severity zizmor findings in workflows

Suppress 2 high-severity zizmor dangerous-triggers findings that are
intentional design:

- dangerous-triggers (2): claude_pr_review.yml and on_opened_pr.yml both
  use workflow_run, which runs from the default branch with this repo's
  context (never a fork's copy). Fork PRs cannot alter behavior or access
  secrets, so the trigger is safe here. Added inline
  # zizmor: ignore[dangerous-triggers] with justification.

No unpinned-uses findings: all uses: refs are internal
aws-deadline/*@mainline reusable workflows, allowed as ref-pin by the
central config.

Signed-off-by: Stephen Crowe <6042774+crowecawcaw@users.noreply.github.com>

* ci: add Security Scan stub calling the reusable org workflow

Adds .github/workflows/security_scan.yml, a thin stub that calls the
central reusable_security_scan.yml in aws-deadline/.github@mainline.
Gates PRs on high-severity zizmor findings; new central checks apply
automatically with no per-repo change.

Signed-off-by: Stephen Crowe <6042774+crowecawcaw@users.noreply.github.com>

---------

Signed-off-by: Stephen Crowe <6042774+crowecawcaw@users.noreply.github.com>
…ws-deadline#253)

* feat: add Lambda + EventBridge job event Slack notification sample

Add a CloudFormation sample that connects an AWS Lambda function to Deadline
Cloud job events via Amazon EventBridge. An EventBridge rule matches
"Job Run Status Change" events with a terminal (SUCCEEDED or FAILED) status
and invokes a Lambda function that posts a notification to Slack using an
incoming webhook. The webhook URL is held in a Lambda environment variable so
it can be rotated without redeploying.

Demonstrates the general mechanism for reacting to Deadline Cloud job events,
using Slack notifications as the concrete scenario.

Signed-off-by: Stephen Crowe <6042774+crowecawcaw@users.noreply.github.com>

* fix: handle Slack POST errors in job events sample Lambda

Wrap the webhook POST in try/except for urllib HTTPError and URLError so a
mistyped, revoked, or rate-limited webhook logs a clear message to CloudWatch
Logs and returns, instead of raising an opaque stack trace and triggering
silent asynchronous Lambda retries. Addresses PR review feedback.

Signed-off-by: Stephen Crowe <6042774+crowecawcaw@users.noreply.github.com>

* fix: also catch OSError (timeouts) around Slack POST

A read timeout on the webhook POST raises TimeoutError, which is an OSError
but not a URLError, so it escaped both except clauses and would propagate --
triggering the async Lambda retries the handler tries to avoid. Add an OSError
clause to cover socket timeouts and other low-level I/O errors. Addresses PR
review feedback.

Signed-off-by: Stephen Crowe <6042774+crowecawcaw@users.noreply.github.com>

* docs: note other messaging apps with incoming webhooks

Add a section listing messaging apps that support the same incoming-webhook
style (Microsoft Teams, Discord, Google Chat, Mattermost) with links to each
app's docs on creating a webhook, and note that the JSON body needs adjusting
per app. Addresses PR review feedback.

Signed-off-by: Stephen Crowe <6042774+crowecawcaw@users.noreply.github.com>

---------

Signed-off-by: Stephen Crowe <6042774+crowecawcaw@users.noreply.github.com>
Merge the base and persistent-volume scripts into one, improve logging
and error handling, and add helper functions to reduce verbosity.

Signed-off-by: Michael Yuan <160265179+yuanmich2@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants