youssefhassan13/low-guidance-cfg-sweep
Sub-CFG guidance sweep (g = 0 → 2), SDXL + SD 3.5 Exploratory. Not pre-registered. Not a result. No hypothesis was committed before these runs, there is no pre-specified statistical model, and no p-values are reported anywhere in this dataset. The sibling Exp 03 dataset is pre-registered, with commit dates as proof. This one is not. Treat it as a reason to design an experiment, not as evidence for a claim. From the Operating System Hypothesis project. Exp 01 and Exp 03 both… See the full description on the dataset page: https://huggingface.co/datasets/youssefhassan13/low-guidance-cfg-sweep.
Sub-CFG guidance sweep (g = 0 → 2), SDXL + SD 3.5
Exploratory. Not pre-registered. Not a result. No hypothesis was committed before these runs, there is no pre-specified statistical model, and no p-values are reported anywhere in this dataset. The sibling Exp 03 dataset is pre-registered, with commit dates as proof. This one is not. Treat it as a reason to design an experiment, not as evidence for a claim.
From the Operating System Hypothesis project. Exp 01 and Exp 03 both swept classifier-free guidance from 1.0 upward, because that is where diffusers turns CFG on. This looks at the region below that boundary.
What is here that is not on GitHub
The 220 generated PNGs. Every text artifact is also in the public repo; the images are gitignored there because of their size.
The library behaviour this had to work around
Both pipelines gate CFG on guidance_scale > 1:
StableDiffusionXLPipeline.do_classifier_free_guidance→self._guidance_scale > 1 and ...StableDiffusion3Pipeline.do_classifier_free_guidance→self._guidance_scale > 1
So a naive sweep of 0 → 2 returns five byte-identical images for g ≤ 1 and only four distinct points above it. The flat floor would be an artifact of the library, not of the model. sweep_low_g.py forces the CFG branch on at every value, so pred = pred_uncond + g * (pred_cond - pred_uncond) runs throughout and g = 0 is the pure negative-branch render.
check_g0.py is the validity check: if the patch had not taken, g = 0 would still show the prompt. It asserts all six prompts collapse to one identical image per seed at g = 0, and it passes on all 220 images.
"Unconditional" is not one thing across architectures. On SDXL the g = 0 image is not the empty-prompt baseline — model_index.json sets force_zeros_for_empty_prompt: true, so the negative branch is a literal zero vector, while uncond_s{seed}.png is the encoding of the empty string. On SD 3.5, which passes an explicit negative_prompt="", the two coincide.
Design
- Guidance: 0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0 (CFG forced on throughout)
- Prompts: the 6 from Exp 03's pre-registration, verbatim
- Seeds: 42, 43 — only two, which is the binding limit on everything below
- Fixed: 25 steps, 1024×1024
- Models: SDXL base 1.0 (UNet) and SD 3.5 medium (MMDiT)
- Judges: Qwen3-VL-32B (local) and Claude Sonnet 5, on Exp 03's rubric, blind and shuffled
What it looks like
Every Klüver field declines as guidance rises, on both models, under both judges — all 20 field × model × judge correlations are negative. Same sign as Exp 03, roughly double the magnitude over this window, consistent with the structure being a property of the prior that guidance suppresses. There is no U-shape.
The judge disagreement is the interesting part
Composite quadratic-weighted κ is +0.710 (SDXL) and +0.661 (SD 3.5), across two different model families. But that headline averages two regimes that fail in opposite directions on the two models:
Both are range restriction, mirrored. On SDXL the low-g cells are ceiling-pinned for one judge only: Qwen scored 3-on-all-four-ordinal-fields for 26 of 48 low-g images, Claude for 0 of 48 — so the flat maximum is a property of that judge, not of the images. On SD 3.5 the high-g cells sit near zero for both, and tiling at g ≥ 1 is undefined outright because both judges scored every image 0.
Agreement is strongest exactly where the scores move. If you are building a VLM-as-judge pipeline, that is the most transferable thing here.
Layout
sdxl/
p{prompt}_g{guidance}_s{seed}.png # conditioned outputs, 9 guidance values
uncond_s{seed}.png # empty-prompt baseline
judgements_claude.json # Claude Sonnet 5, blind
judgements_qwen_32b.json # Qwen3-VL-32B, blind
judgements_qwen_32b_raw.json # raw replies, kept as audit trail
metadata.json
figures/ # contact sheets, one row per prompt
sd35/ (same layout)
README.md, analysis.md, report.json
manifest.jsonLimitations, stated up front
- Unregistered and exploratory. No pre-specified hypothesis, model, or correction.
- Two seeds. Too thin for any claim about the character of the prior, and the two disagree sharply — at seed 42 SDXL's prior is a dense floral tiling and SD 3.5's is a readable scene; at seed 43 that reverses.
- n = 2 at g = 0. All six prompts render one identical image per seed, so that column holds two distinct images, not twelve. The analysis deduplicates by SHA before computing means, CIs and the pooled ρ.
- Rubric ceiling. The scale stops at 3 and one judge reaches it often at low g.
- Not poolable with Exp 03. Its g = 1.0 point was CFG-off; this one's is CFG-on.
Provenance
- Code and full write-up: https://github.com/youssefhassan/operating-system-hypothesis-public/tree/main/experiments/_unregistered_low_guidance
- Git commit:
417dfd03a8e8bfff90e2a605f5d305a0f9cbfc82 - Exported: 2026-09-03T19:07:43.549310+00:00
- Files: {"png": 220, "figure": 4, "text": 11}
License
MIT, same as the parent repository. Generated images are research artifacts; the underlying Stable Diffusion weights remain under their own model licenses.
