AINovice2005's picture
|
download
raw
4.26 kB
# 13 · Synthetic Multimodal Data Generation (CPU)
Build a synthetic image-caption dataset by captioning pre-generated
Stable Diffusion images and scoring how well the generated caption
aligns with the original prompt — entirely on CPU.
## What this example shows
- Using an existing Hub dataset of AI-generated images as a synthetic data source (no GPU inference)
- Free quality filtering using a dataset's precomputed metadata (`image_nsfw`, `prompt_nsfw`)
- CPU-based image captioning with `transformers` (BLIP-base)
- CPU-based semantic similarity scoring with `sentence-transformers` (MiniLM)
- Lazy global model loading to avoid reloading per-row
- A multi-stage funnel report and asset checks on the final filtered output
## Dataset
[`poloclub/diffusiondb`](https://huggingface.co/datasets/poloclub/diffusiondb) (`2m_random_1k` config) — 1,000
random (image, prompt, generation-parameter) triples from Stable
Diffusion generations submitted to the DiffusionDB Discord. Only
`SAMPLE_SIZE` (default **40**) rows are used to keep CPU runtime short.
| Field | Description |
|-------|-------------|
| `image` | Generated image (PIL) |
| `prompt` | Text prompt used to generate it |
| `seed`, `cfg`, `sampler`, `step` | Generation parameters |
| `image_nsfw`, `prompt_nsfw` | Precomputed NSFW scores (0-1, or -1 if unscored) |
## Asset graph
```
diffusiondb_sample
nsfw_filtered (drop image_nsfw/prompt_nsfw >= 0.5)
synthetic_captions (BLIP-base captions each image, CPU)
caption_alignment_scores (MiniLM cosine similarity: prompt vs. caption)
synthetic_dataset_final (keep alignment_score >= 0.2)
synthetic_generation_report
[checks]
```
## Key implementation details
**Lazy global model loading** — avoids reloading BLIP/MiniLM on every
row by caching at module scope:
```python
_blip_model = None
def _load_blip():
global _blip_model
if _blip_model is None:
_blip_model = BlipForConditionalGeneration.from_pretrained(...)
return _blip_model
```
**Per-image captioning loop** (no batching — keeps CPU memory bounded):
```python
for example in nsfw_filtered:
inputs = processor(example["image"].convert("RGB"), return_tensors="pt")
out = model.generate(**inputs, max_new_tokens=30)
caption = processor.decode(out[0], skip_special_tokens=True)
```
**Alignment scoring** via sentence-embedding cosine similarity:
```python
emb = model.encode([prompt, generated_caption], convert_to_tensor=True)
score = float(util.cos_sim(emb[0], emb[1]))
```
## Thresholds
| Parameter | Default | Purpose |
|-----------|---------|---------|
| `SAMPLE_SIZE` | 40 | Rows processed; controls CPU runtime |
| `NSFW_THRESHOLD` | 0.5 | Drop rows scoring above this on image/prompt NSFW |
| `ALIGNMENT_THRESHOLD` | 0.2 | Minimum caption↔prompt cosine similarity to keep |
All three are tunable constants at the top of `assets.py`.
## Asset checks
| Check | Severity | Condition |
|-------|----------|-----------|
| `check_no_empty_captions` | ERROR | No empty `generated_caption` values in final output |
| `check_mean_alignment` | WARN | Mean `alignment_score` in final dataset ≥ `ALIGNMENT_THRESHOLD` |
## Storage layout
```
.dagster_hf_storage/
├── diffusiondb_sample/
├── nsfw_filtered/
├── synthetic_captions/
├── caption_alignment_scores/
└── synthetic_dataset_final/
```
`synthetic_generation_report` returns a plain `dict` and is not persisted.
## How to run
```bash
pip install dagster dagster-hf-datasets Pillow
pip install torch --index-url https://download.pytorch.org/whl/cpu
pip install transformers sentence-transformers
cd dagster_hf_datasets_examples
dagster dev -m synthetic_multimodal_data.definitions
```
First run downloads BLIP-base (~990MB) and MiniLM (~90MB) to the local
HF cache — subsequent runs reuse the cache. With `SAMPLE_SIZE=40`,
expect the full pipeline to complete in roughly 1-3 minutes on a
modern CPU.
Materialize sequentially from `diffusiondb_sample` through
`synthetic_dataset_final`, then `synthetic_generation_report`, then
run checks from the **Checks** tab on `synthetic_dataset_final`.

Xet Storage Details

Size:
4.26 kB
·
Xet hash:
267d3c84e8d44224ac13dfcbf17c348503efa50e944cd4af0745468b563e6016

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.