GeoCore-9B

Towards Geo-Aware Generative Foundation Models in Earth Observation

Jeonghyeok Do  Β·  Munchurl Kim

Korea Advanced Institute of Science and Technology (KAIST)

Project Page Code License

Text-conditioned generation compared with prior methods

A 9-billion-parameter generative foundation model for Earth Observation, trained from scratch exclusively on EO data. GeoCore-9B is a Flow Matching Diffusion Transformer that conditions generation on text and continuous geospatial metadata β€” ground sample distance (GSD), latitude and longitude.

2026-08-04 β€” corrected weights. The initial upload accidentally contained an EMA state that was never updated during training (pure initialization weights β€” see GitHub issue #2). The current files are the final 300K-step training weights, verified to load strictly and denoise correctly. If you downloaded the weights before this date, please re-download and check them against SHA256SUMS.

Model details

Parameters 9.24 B
Weights final training weights (non-EMA), bfloat16, sharded safetensors
Included frozen Flux.2 VAE in vae/ (Apache-2.0, Black Forest Labs)
Architecture Flow Matching DiT β€” 8 double-stream + 24 single-stream blocks, hidden 4096, 32 heads
Conditioning CLIP + T5 text embeddings, GSD, latitude, longitude
Training data Git-10M
Training 300K steps, global batch 1024, AdamW lr 1e-4, bf16, DeepSpeed ZeRO-2, 8x B200
Resolution 256x256

Training used a Geospatial Semantic Alignment (GSA) loss that aligns intermediate DiT features (block 8) with a frozen DINOv3-Sat teacher, weighted by mu = 0.5. GSA is training-only β€” the teacher and projection head are not needed for inference, and the exported weights add no overhead.

Usage

These weights use a custom Flux2 architecture, so load them with the model definition from the GitHub repository rather than a stock diffusers pipeline.

import torch
from huggingface_hub import snapshot_download

from models.flux2 import Flux2, GeoCore9BParams
from inference import load_state_dict

path = snapshot_download("JeonghyeokDo/GeoCore-9B")

model = Flux2(GeoCore9BParams()).to("cuda", torch.bfloat16)
model.load_state_dict(load_state_dict(path), strict=True)
model.eval()

Sampling, including the Euler flow-matching sampler and classifier-free guidance over both text and metadata, is provided by inference.py:

python inference.py \
    --ckpt /path/to/GeoCore-9B \
    --vae /path/to/GeoCore-9B/vae \
    --prompt "A satellite view of a highly dense urban city with towering skyscrapers" \
    --lon 126.97 --lat 37.56 --res 0.0 \
    --num-samples 4 --out samples/

Conditioning inputs

  • res β€” resolution index, defined as 17 - z for Google XYZ tile zoom z. res = 0 is roughly 1.2 m/px at the equator; each +1 doubles the GSD.
  • lon, lat β€” degrees.
  • Any field set to -999.0 falls back to the model's learned null embedding for that field, so metadata is fully optional.

The frozen VAE is included

vae/ in this repository holds the frozen Flux.2 autoencoder that encodes and decodes the latents, so snapshot_download gives you everything the model needs:

python inference.py --ckpt /path/to/GeoCore-9B --vae /path/to/GeoCore-9B/vae ...

models/vae_flux2.py reads it directly (load_autoencoder), and vae/config.json is included so diffusers >= 0.37 can load it too:

from diffusers import AutoencoderKLFlux2
vae = AutoencoderKLFlux2.from_pretrained("JeonghyeokDo/GeoCore-9B", subfolder="vae")

CLIP and T5 text encoders are still downloaded from the Hub at runtime.

Do not substitute ae.safetensors from FLUX.2-dev. It holds the same autoencoder weights, but under the FLUX Non-Commercial License v2.1, whose Β§4(a)(iii) forbids "surveillance purposes, including all research and development related to surveillance" β€” a clause that Earth-observation work should not have to argue about. The copy shipped here is Apache-2.0, and the two were verified identical by pairing every tensor on value: 250 of 251 pair one-to-one with a worst deviation of 7.802e-03 (bf16 rounding); the odd one out is a BatchNorm step counter. In bf16, the precision this model runs in, latents and reconstructions are bit-identical.

Limitations

  • Trained on 256x256 RGB optical imagery; other resolutions and sensor modalities require adaptation.
  • Git-10M coverage is uneven across the globe, so generation quality varies by region.
  • Geospatial conditioning reflects correlations in the training corpus and is not a substitute for real observations of a location.

License and attribution

GeoCore-9B is released under Apache-2.0, and so is every weight needed to run it.

model-*.safetensors (the 9.24B DiT) β€” Copyright 2026 Jeonghyeok Do and Munchurl Kim, Apache-2.0. Trained from scratch on Git-10M; not derived from any FLUX checkpoint.

vae/ (the frozen 84M autoencoder) β€” Copyright Black Forest Labs, Apache-2.0. This is an unmodified, byte-identical redistribution of black-forest-labs/FLUX.2-klein-base-4B vae/diffusion_pytorch_model.safetensors and its vae/config.json, bundled here only so the model is usable in one download. Verify it against upstream:

sha256  ca70d2202afe6415bdbcb8793ba8cd99fd159cfe6192381504d6c4d3036e0f04  vae/diffusion_pytorch_model.safetensors
sha256  0d6dfb69ae95a5e2ac9836284bbb63d8b38ce67b25ba2dff380752b2a10ab948  vae/config.json

Those digests are the upstream files' own. A copy of the Apache License 2.0 as distributed with that model is included as LICENSE-FLUX2-VAE.md. Black Forest Labs neither endorses nor is affiliated with GeoCore-9B; the attribution above is a statement of origin, not of sponsorship.

The Git-10M training corpus is CC BY-NC-ND 4.0, which restricts (re)training on that data to non-commercial use.

Citation

@article{do2026geocore,
  title   = {GeoCore-9B: Towards Geo-Aware Generative Foundation Models in Earth Observation},
  author  = {Do, Jeonghyeok and Kim, Munchurl},
  year    = {2026}
}
Downloads last month
34
Safetensors
Model size
9B params
Tensor type
BF16
Β·
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support