Fire the shots.
Let the GPU find the rock.
Full-waveform inversion recovers what lies underground by simulating seismic waves and adjusting a velocity model until the simulated recordings match the real ones. Watch it rebuild the Marmousi2 benchmark from a blur, then change the shots, iterations and starting model and run it again on an NVIDIA L4. Chalk deploys the PyTorch inversion behind an API from one Python file.
Marmousi2, rebuilt from its own echoes
The inversion starts from a blurred velocity model and only ever sees what the receivers recorded. Play it back and watch the faulted wedges and thin beds of the Marmousi2 benchmark emerge, shallow layers first, as the misfit between simulated and observed shots falls. Then fire more or fewer shots, start further from the answer, and run it yourself.
How far the simulated shots are from the observed ones, relative to the starting model at the same frequency. Each stage starts again at a higher frequency, so the misfit jumps before it falls.
The observed shots are simulated through the true model with the same acoustic wave equation, the textbook setup for testing an inversion; field data adds noise, elastic effects and an unknown source. The model is a 9 km × 3.5 km window of the AGL Elastic Marmousi (Marmousi2) P-wave velocity by Martin, Wiley and Marfurt, © 2004 Allied Geophysical Laboratory, University of Houston, CC BY 4.0, resampled to 25 m. The recorded run is the stream the button produces, saved from the deployed API; times are wall-clock for the whole inversion.
How it works
Every iteration simulates every shot forward through the current model and back again for the gradient: thousands of wave-equation time steps over the whole grid, which is exactly the work a GPU is built for.
Simulate the survey
Shots fired along the surface send acoustic waves into a velocity model; receivers every 25 m record what comes back. Each shot is a finite-difference solve on the GPU.
Measure the misfit
The simulated recordings are compared with the observed ones. Where a layer sits too deep or too slow, its reflections arrive late, and the difference says so.
Backpropagate through the physics
Deepwave makes the wave equation differentiable in PyTorch, so autograd computes the adjoint-state gradient of the misfit with respect to every cell's velocity.
Low frequencies first
The inversion runs at 4, then 7, then 10 Hz. Long wavelengths fix the broad structure before short ones add the faults and thin beds.
Same code and the same answer on every device: the misfit after 30 iterations agrees to three digits. One L4 runs the inversion about 75 times faster than 32 cores of a Xeon Platinum 8468V, and an H100 about 110 times. Each iteration steps the wave equation 1,250 times over all 50,760 cells, forward and back, for every shot: bandwidth-bound stencil work that a GPU runs in parallel. The 4-core run was stopped after 30 iterations.
An inversion behind an API
The inversion is about 150 lines of PyTorch around Deepwave, Alan Richardson's MIT-licensed wave propagation library with CUDA kernels. A FastAPI server streams each iteration as JSON lines, and one ScalingGroup puts it on an L4.
Swap in your own survey geometry, wavelet and starting model, or point the same pattern at reverse-time migration, elastic inversion or a surrogate model trained on the results.
Deepwave on GitHubimport json, httpx
params = {"shots": 20, "iterations": 120, "start_blur_m": 250}
with httpx.stream("POST", f"{URL}/api/run", json=params, timeout=None) as r:
for line in r.iter_lines():
msg = json.loads(line)
if msg["type"] == "step" and "velocity" in msg:
print(f"iteration {msg['iteration']:4d} {msg['stage_hz']:4.0f} Hz"
f" misfit {msg['misfit']:6.3f} wall {msg['wall_s']:6.1f}s")
# iteration 40 4 Hz misfit 0.009 wall 10.0s
# iteration 80 7 Hz misfit 0.002 wall 20.1s
# iteration 120 10 Hz misfit 0.001 wall 30.2sWhat Chalk handles
The GPU, the image, the endpoint and the scaling, so the physics is the only thing you maintain.
PyTorch on a GPU, as a service
The inversion is ordinary PyTorch code. Chalk builds the image, schedules it on a GPU and puts an HTTPS endpoint in front of it.
Hardware in one argument
An L4 for this 9 km slice; an H100 or several for full surveys and 3D. Chalk provisions the node and the drivers.
Ready means ready
The replica runs a short inversion before its readiness probe passes, so traffic only reaches a GPU that has already solved the wave equation.
Fan out shots and scenarios
Shots are independent until the gradient is summed. Scale the group out to split a survey, or to run many starting models and frequency schedules at once.
Stream results as they land
The API streams the model every few iterations, so a long inversion shows its progress from the first second.
Runs in your cloud
Chalk deploys into your own AWS, GCP or Azure account, so proprietary surveys and velocity models never leave it.
Image the subsurface on demand
Inversion, migration or seismic interpretation models: talk to an engineer about running your geophysics on GPUs in your own cloud.