Two People Taught a Video Model to Shoot VR for $12.50 Each. The Recipe Is One Sentence.
Two independent LoRAs, three days apart, converged on the same rank-32 recipe for teaching MiniMax H3 an entirely new frame layout. Both published the pipeline. Here is the mechanism, and how to run it on whatever format you need.
Ninety-five percent of the effort in these two projects went into things that are not machine learning. Cropping letterbox bars. Forcing constant frame rate. Checking that the left half of a frame correlates with the right half. Writing a regular expression to throw out theme-park footage. The part that people think of as the hard part, the training, was 2500 steps on one rented H200, about 3.9 hours, and US$12.50.
That is the actual shape of a format LoRA, and both authors documented it in public within three days of each other without coordinating. One taught MiniMax H3 to shoot VR180 stereoscopic video, where a single frame carries a left-eye view on its left half and a right-eye view on its right. The other taught the same base model to shoot 360-degree equirectangular video, a full sphere wrapped around the viewer. Different geometries, same recipe, same price, both with the pipeline in the repo.
The interesting part is what the adapter learns. It is not geometry.
The mechanism is a sentence
Here is the line that does the work in the VR180 project, sitting in training/pipeline_config.yaml as layout_sentence:
"Stereoscopic VR180 video shown side by side: the left half is the left-eye view and the right half is the right-eye view of the same 180-degree scene, nearly identical with a slight horizontal offset."
That exact string was prepended to every single training caption, and it gets prepended to every inference prompt too. The 360 project does the same thing with its own layout sentence about spherical projection and horizon placement. Both then set a trigger word (vr180sbs and equirect360) that the caption model would never emit on its own.
Why it works is spelled out in the config's own comment, and it is the most useful sentence in either repo:
"The pilots learned the wide-angle look before the two-eye split, so spelling the layout out gives the text encoder something concrete to bind the trigger to."
Read that carefully. A trigger token by itself is an arbitrary handle. The model has to learn from scratch what it points at, using only the visual evidence in fifty clips. That is a lot to ask. But if every caption pairs the trigger with the same plain-English description of the frame arrangement, the text encoder already knows what most of those words mean, and the trigger becomes a shortcut to a region of prompt space the model can already partly reach. You are not teaching a new concept. You are naming an arrangement and then reinforcing the name.
The pilot results back this up, and they are the most honest numbers in either repo. At 1000 steps in the 21:9 bucket, the VR180 pilot produced a usable stereo pair on one prompt out of four. At 1000 steps in a 16:9 bucket, zero out of four. The production run (21:9, layout captions, 2500 steps) hit four out of four. Two variables moved together there, so this is not a clean ablation. It is still the difference between a thing that works and a thing that does not, published by the person who paid for both runs.
This generalizes past VR. If your format can be described in one consistent sentence and shown fifty times, it is probably trainable. Split-screen comparison layouts. Anamorphic squeeze. Vertical triptych. Storyboard contact sheets. Nobody has to build you a feature for it.
The squeeze is a workaround, and the config admits it
Both LoRAs generate at a 21:9 aspect ratio and then get stretched back to 2:1 afterward. Both READMEs describe this as the trick. It is really a workaround, and I only know that because the VR180 config left the evidence in:
train:
endpoint: minimax/h3/t2v/trainer
# fal-internal alternative (private auth): exact 2:1 bucket, no squeeze needed.
internal:
endpoint: fal-ai/minimax-h3-trainer-internal/text-to-video-audio
custom_width: 896
custom_height: 448
The public trainer offers fixed buckets. 21:9 at medium resolution is 896x384, which is the closest public shape to a 2:1 frame. There is an internal endpoint that takes arbitrary width and height, which would let you train at exactly 896x448 with no distortion at all, and it needs private auth.
So the whole squeeze-and-unsqueeze dance exists because a parameter is not exposed on the public tier. Everything downstream follows from that: the per-eye 1.17:1 stretch during training, the ffmpeg rescale to 1536x768 during packaging, and the note in the 360 repo that the wrap seam almost closes and not quite, because the trainer has no circular-convolution option either.
That is worth knowing before you plan your own run, because it means the recipe is tuned to a constraint rather than to the problem. If you have access to a trainer where you control the bucket, skip the squeeze entirely and your version of this is simpler than theirs.
Put this into practice
You need about 50 to 125 source clips, yt-dlp, ffmpeg, and a fal key. Budget two evenings for data and one afternoon for training.
1. Collect the format, not the subject. The VR180 project pulled from Google's Stereo4D index, a curated list of 5,313 YouTube VR180 videos, taking two segments of six seconds from up to forty videos. The 360 project used 124 clips of about 5.5 seconds from 47 real 360 videos, spread across three deliberately different lanes: realism, psychedelic, and cavern. That spread is intentional. You want the layout to be the only thing every clip has in common.
2. Write the exclusion rule before you download anything. This line is in the VR180 config and it is the least glamorous, most professional thing in either repo:
exclude_title_regex: "(?i)disney|small world|magic kingdom|epcot|mickey|minnie|universal studios|marvel|star wars|pixar|nintendo|pokemon|harry potter|k-?pop|concert|..."
The comment says why: "franchise/brand-heavy footage is a liability for a published LoRA." Theme-park and concert footage is abundant in VR180, which is exactly why it will dominate your dataset if you let it, and exactly why you should not publish an adapter trained on it.
3. Fit the bucket exactly so the platform does nothing. This is the step that decides whether your run works, and it will not announce itself. Scale every clip to precisely 896x384 at 24 fps constant frame rate, so fal's own cover-and-center-crop becomes a no-op. Frame count matters too: the config wants 124 frames, and notes the constraint as 17n+5, which at 24 fps is 5.17 seconds, exactly what the model renders at duration=5. Fetch a second or so of extra tail, because the trainer takes the head window and frame-rate conversion can leave you short.
4. Keep the audio, and check it is real audio. MiniMax H3 trains video and audio jointly, and the trainer will substitute silence for a clip with no audio track. The config sets require_audio: true with a warning I would not have thought of: a track that exists but is silent is not detected. Keep 32 kHz stereo throughout.
5. Add the boring sanity gates. The VR180 prep step enforces min_stereo_similarity: 0.55 so the left and right halves must actually correlate, a source_aspect_range of 1.7 to 2.15 after bar-cropping, letterbox detection, and crf: 16. Set strict_dataset: true on the trainer so a bad clip returns a 422 instead of silently becoming a blank prompt or a silent track. Every one of these exists because something got through once.
6. Caption with a model that can hear. Both projects used a Gemini Flash Lite through fal's openrouter/router/video route, which sees audio as well as video, at 40 to 80 words per clip describing scene, camera and soundscape. The two repos disagree on the version, which is worth knowing if you are trying to reproduce either exactly: the VR180 config pins google/gemini-3.5-flash-lite, and the 360 card names only "Gemini Flash Lite" with no version at all. Then prepend the layout sentence at zip time and pass the trigger through the trainer's own trigger_phrase field. One config comment is emphatic about this: bake_trigger: false with the note "never both." Put the trigger in the caption text or in the trainer field, not in each.
7. Pilot before you spend. Both projects used rank 32 with alpha equal to rank, on the qkv_proj and out_proj attention projections, AdamW at 2e-4 with linear decay, batch 1, 2500 steps. Run the 1000-step pilot preset first at your target aspect ratio and check whether the layout appears at all. The prod comment is blunt about why 2500: "pilots were still learning at 1000 steps @2e-4."
8. Evaluate same-seed at scale 0 versus scale 1. Generate each eval prompt twice with an identical seed, once with the LoRA mathematically absent and once at full strength. This is the only comparison that isolates what your adapter did, and both repos ship the resulting contact sheets.
9. Package it for the target device. For 360, two commands:
ffmpeg -i out.mp4 -vf "scale=1536:768:flags=lanczos,setsar=1" -c:v libx264 -crf 16 \
-pix_fmt yuv420p -c:a copy tmp.mp4
python spatialmedia -i --v2 --stereo=none -p equirectangular tmp.mp4 out_360.mp4
The VR180 version differs only in the metadata flags: -s left-right and a bounds argument that crops 90 degrees per side. spatialmedia is Google's spatial-media tool, and without that second command your file is just a squashed rectangle that no headset will recognize.
At inference, both need prompt_expansion_mode: disabled, scale 1.0, and the minimax/h3 route. The 8-step h3-max turbo route degrades the stereo pair, and fal's 2K and 4K outputs are SeedVR upscales of the 768p pass rather than native renders.
Where this gets thin
One of the two model cards was written by an LLM, and says so. The 360 repo carries an author's note: written by GLM 5.3 Flash, "may not be entirely accurate or represent the authors intent." The weights, sample clips and training scripts in that repo are all real and checkable. The prose describing them, including the loss curve and the cost figures, is a machine summary of the author's work rather than the author's own account. I have used its numbers here because the VR180 repo independently reports the same hyperparameters and the same $12.50, but if only one repo existed I would treat those figures differently.
The shipped stereo metrics do not measure what the prose claims. The VR180 repo includes eval_stereo_metrics.json, which is genuinely good practice. What it records is global alignment between the two halves: with the LoRA off, mean disparity across the four clips runs from negative 20.33 to 24.0 pixels with standard deviations as high as 20.34, and with it on, the same four sit at 0.33, 0.0, 0.0 and negative 1.0. Aligned mean absolute difference falls sharply too, from 73.5 to 14.1 on the worst case. That is solid evidence the halves are a correctly registered pair. It is not evidence for the README's separate claim that near objects carry 3 to 7 pixels of per-object disparity, which is a different measurement and is not in the file.
Eight files is the entire evaluation. Four prompts, one seed, two scales. Both authors say so plainly, and both end their limitations section with the same instruction: put it in a headset before trusting it.
The known artifacts are structural rather than tuning problems. The 360 seam can show a faint discontinuity at the 180-degree wrap because the trainer has no circular convolution. H3's base training is full of dolly and pan footage, so it invents camera movement on some prompts and drags distortion across the projection; "static camera, locked tripod" in the prompt helps and does not fix it. The VR180 version inherits dark porthole vignettes at the outer edge of each eye from camera-native footage, and 20 of its 50 clips come from a single source channel, so expect a bias toward first-person outdoor walks.
Your data problem is entirely yours. Neither repo redistributes a single training frame, correctly. Both note that clips came from YouTube under YouTube's standard license, and the VR180 config has a require_cc flag set to false with a comment that Creative Commons Attribution uploads are rare, around 3% of the pool. Read that flag as the open question it is.
And the weights carry a territory clause. Both adapters derive from MiniMax H3, whose Community License grants rights in an applicable territory that excludes the European Union, the United Kingdom, the Republic of Korea and the United States. That covers most people likely to read this.
What I would try next
The recipe here is cheaper than the machine that runs it, which is a strange and new situation. Twelve dollars and fifty cents buys you a rank-32 adapter that changes what shape a frontier-scale video model draws. The gating factor is not compute and it is not skill. It is having 50 clean examples of a layout and one sentence that describes it well.
So the question I keep turning over is which formats nobody has bothered with because they assumed it was expensive. Two-page comic spreads with consistent gutters. Technical exploded views. Split-screen A/B layouts for demonstration footage. Fisheye. Anything with a fixed spatial contract and no product manager behind it.
Two people proved the same recipe on two different geometries in one week, which is a much stronger signal than either would have been alone. The obvious next move is a third geometry that has nothing to do with VR, trained by someone who reads the pipeline config rather than the README.
If you run this on a format nobody has tried, publish the config and the failed pilot too. That is the part both of these repos got right, and it is the part that made a second person's run possible three days after the first.
Sources
- VR180 stereoscopic side-by-side LoRA, with
training/pipeline_config.yamlandtraining/eval_stereo_metrics.json - Equirectangular 360 LoRA, with the full Node.js pipeline in
scripts/ - Google's Stereo4D, the validated stereo footage index
- Google spatial-media, the metadata tool both workflows end in
- MiniMax H3 Community License
Medium metadata
Title: Two People Taught a Video Model to Shoot VR for $12.50 Each. The Recipe Is One Sentence.
Subtitle: Two independent LoRAs, three days apart, converged on the same rank-32 recipe for teaching MiniMax H3 an entirely new frame layout. Both published the pipeline.
Tags: AI Video Generation, LoRA, Virtual Reality, Machine Learning, Creative Technology
Suggested publication: Towards Data Science, Better Programming, or self-published
Reading time: about 9 minutes