← Blog
September 1, 2025

Lea y procese GeoTiffs en la GPU (cuCim + rasterio)

Puede ejecutar cálculos de ráster pesados en una sola GPU si carga datos en azulejos y mantén el georreferenciación recta. Esta guía muestra un patrón limpio para usar con su proveedor de servicios de GPU rasterio para metadatos y E/S, Cucimo/taza para la velocidad, y pyproj cuando necesite una reproyección.

La verdad es que no todos los GeoTIFF se leen de forma nativa en la GPU. La ruta confiable es Lectura de CPU → cálculo de GPU → escritura de CPU, hecho en ventanas que coinciden con el ordenamiento interno del archivo. cuCim puede leer muchos TIFF en mosaico directamente en la GPU; cuando no puede, igual ganas copiando Windows a CuPy antes de los cálculos.

1) Elige una imagen

Dos buenas opciones:

A) Imagen RAPIDS (inicio rápido)
<24.xx>docker.io/rapidsai/rapidsai: -cuda12-runtime-ubuntu22.04-py3.10

B) Base CUDA + bibliotecas de Python
Comience desde un entorno de ejecución de CUDA (por ejemplo, Ubuntu 24.04/ CUDA 12.x) y, a continuación, instale:

# micromamba (recomendado)
micromamba create -y -n geo -c conda-forge -c rapidsai\
python=3.10 Brazalete rasterio pyproj cupy cucim
micromamba active geo
python -c «importar rasterio, pyproj, cupy, cucim; print ('ok')»

La plantilla debe establecer:

  • NVIDIA_VISIBLE_DEVICES=Todos
  • NVIDIA_DRIVER_CAPABILITIES=Computación, utilidad

Control de la integridad del interior del contenedor:

nvidia-smi

2) Usa GeoTIFF (COG) optimizados para la nube siempre que puedas

Tienda COGs azulejos internos y vistas generales que hacen que la lectura en ventanas sea predecible. Incluso en el caso de los archivos locales, el diseño COG mantiene la E/S rápida y funciona bien con el ordenamiento en teselas de la GPU. Si puedes, conviértelo una vez en un COG con 512 × 512 o 1024 × 1024 mosaicos y LZW/Deflate/ZSTD.

Start in seconds with the fastest, most affordable cloud GPU clusters.

Launch an instance in under a minute. Enjoy flexible pricing, powerful hardware, and 24/7 support. Scale as you grow—no long-term commitment needed.

Try Compute now

3) Patrón A: lectura de CPU → cálculo de GPU → escritura de CPU (valor predeterminado robusto)

Esto funciona en cualquier GeoTIFF y mantiene intacta la georreferenciación.

Ejemplo: NDVI de bandas RED/NIR

importar rasterio
desde la ventana de importación de rasterio.windows
importar cupy como copla
importar numpy como np

src_path = "scene.tif" # GeoTIFF multibanda (p. ej., banda 3=RED, banda 4=NIR)
dst_path = "ndvi.tif»
BANDA_ROJA, BANDA_NIR = 3, 4

con rasterio.open (src_path) como src:
perfil = src.profile.copy ()
profile.update (count=1, dtype="float32", nodata=np.nan)

tile_w, tile_h = src.block_shapes [0] # usa ordenamiento interno
con rasterio.open (dst_path, «w», **profile) como dst:
para ji, ventana en src.block_windows (1): # iterar mosaicos
red = src.read (RED_BAND, window=window) .astype («float32")
nir = src.read (NIR_BAND, ventana=ventana) .astype («float32")

# pasar a la GPU
red_d = cp.asarray (rojo)
nir_d = cp.asarray (nir)

# NDVI = (NIR - ROJO)/(NIR + ROJO)
denom = nir_d + red_d
ndvi_d = cp.where (denom! = 0, (nir_d - red_d)/denom, cp.nan)

# volver a la CPU y escribir
dst.write (cp.asnumpy (ndvi_d), 1, ventana=ventana)

Por qué funciona esto

  • Empuñaduras Rasterio CRS/Transform/NoData y escribe un GeoTIFF válido.
  • Solo mueves un baldosa a la vez a la GPU, por lo que la VRAM permanece limitada.
  • Funciona con entradas comprimidas; la descompresión se produce durante src.read ().

4) Patrón B: lectura nativa de la GPU con cuCIM (cuando sea compatible)

CuCim puede leer muchos TIFF en mosaico directamente a la GPU sin una matriz de CPU intermedia. Sigues usando rasterio para obtener metadatos y escribir los resultados.

importar rasterio
importar cupy como copla
desde cucim import CUImage
desde la ventana de importación de rasterio.windows

src_path = "scene.tif»
banda_roja, banda_nir = 3, 4

con rasterio.open (src_path) como src:
H, W = altura del eje, ancho del eje
tile_w, tile_h = src.block_shapes [0]

cu = cuImage (src_path)

profile = src.profile.copy (); profile.update (count=1, dtype="float32")
con rasterio.open (» ndvi.tif «, «w», **profile) como dst:
para _, ventana en src.block_windows (1):
col_off, row_off = window.col_off, window.row_off
w, h = ancho de ventana, altura de ventana

# Lea una subregión (x, y, w, h) directamente a la GPU
# Nota: algunos archivos/controladores pueden requerir alternativas; maneje las excepciones.
región = cu.read_region (
ubicación = (col_off, row_off), tamaño = (w, h), nivel = 0
) # devuelve una matriz con bands-last
# corta bandas y muévelas a CuPy
nir_d = cp.asarray (región [..., nir_band - 1], dtype=cp.float32)
red_d = cp.asarray (región [..., red_band - 1], dtype=cp.float32)

ndvi_d = (nir_d - red_d)/cp.where ((nir_d + red_d)! = 0, (nir_d + red_d), cp.nan)
dst.write (cp.asnumpy (ndvi_d), 1, ventana=ventana)

Advertencias

  • El orden de la banda puede ser bandas por última vez; ajustar la indexación.
  • Algunas funciones de GeoTIFF no son totalmente compatibles con CuCim; detecte las excepciones y recurra al patrón A.

5) Reproyección (mantenlo simple)

Realice los cálculos warp una vez en la CPU para producir un cuadrícula objetivoy, a continuación, muestree en la GPU.

importar numpy como np, cupy como cp, rasterio
desde rasterio.warp import calculate_default_transform
desde rasterio.vrt importar WarpedVRT

src = rasterio.open (» scene.tif «)
dst_crs = «EPSG:32633" # ejemplo de UTM
transform, width, height = calculate_default_transform (src.crs, dst_crs, src.width, src.height, *src.bounds)

# Cree una vista distorsionada virtual (rasterio se encarga de la geodesia y el remuestreo)
con WarpedVrt (src, crs=dst_crs, transform=transform, width=width, height=height, resampling=rasterio.enums.resampling.bilinear) como vrt:
profile = vrt.profile.copy (); profile.update (dtype="float32", count=1)
con rasterio.open (» band3_utm.tif «, «w», **profile) como dst:
para _, ventana en vrt.block_windows (1):
arr = vrt.read (3, window=window) .astype («float32")
# haga cálculos de GPU en los mosaicos deformados si es necesario
arr_d = cp.asarray (arr)
#... calcular...
dst.write (cp.asnumpy (arr_d), 1, ventana=ventana)

Por qué este enfoque

  • Tú mantienes geodesia (CRS se transforma y remuestrea los núcleos) en una biblioteca probada en batalla.
  • Aún obtienes aceleraciones de GPU para los vehículos pesados. matemáticas por píxel después de warp.

6) Consejos de rendimiento y VRAM

  • Coincide con el tamaño de bloque del archivo (conjunto de datos.block_shapes) para ventanas; no inventes tamaños impares.
  • Prefiero float32 para los cálculos, a menos que haya demostrado que se requiere FP64.
  • Limitar los mosaicos simultáneos; procesa de 1 a 4 a la vez, según la VRAM.
  • Evite la sobrecarga de Python por mosaico agrupando ventanas y usando bucles simples.
  • Escriba menos archivos de mayor tamaño (o COG con ordenamiento interno) para reducir la sobrecarga de metadatos.

7) Autoevaluación y cálculo de costos

entradas: tamaño de archivo, bandas, tipo d, mosaicos, CRS
hardware: modelo de GPU/VRAM, CUDA, controlador; modelo de CPU
código: versiones (rasterio, cucim, cupy)
métricas: teselas/segundo, MB/s, tiempo de pared, pico de VRAM

Coste por cada 100 GB procesados

cost_por_100 gb = precio_por_hora × horas_pared × (100/(gb_procesado))

8) Solución de problemas

ZOOM DE GPU
Procesa menos teselas o más grandes; moldea en float32; matrices libres (del arr_d; cp._default_memory_pool.free_all_blocks ()).

Resultados extraños
Bandas no coincidentes o falta de manejo de datos. Compruebe el orden de las bandas; no propague ningún dato a la salida.

Lecturas lentas
No es un COG, baldosas pequeñas o una compresión fuerte. Convierte una vez en un COG bien estructurado.

Errores de CUCIM
Vuelva al patrón A y registre la información de creación del archivo para su posterior conversión.

Fragmento de métodos (copiar y pegar)

hardware:
gpu: "<model>(<VRAM>GB)»
conductor: "<NVIDIA driver>»
<CUDA version>cuda: "»
software:
<24.xx>imagen: «rapidsai/rapidsai: -cuda12-runtime-ubuntu22.04-py3.10"
bibliotecas:
<ver>- rasterio: «»
<ver>- primo: "»
<ver>- copar: «»
<ver>- pyproj: "»
entradas:
archivo: "scene.tif (bands=<... >, dtype=<... >)»
<EPSG:...>cuadrícula: «CRS=, transform=< ... >»
correr:
patrón: «lectura de CPU → cálculo de GPU → escritura de CPU (mosaicos)»
tile: "<w>× <h>de block_shapes»
salidas:
wall_seconds: «<... >»
tiles_por_sec: «<... >»
mb_per_sec: «<... >»
notas: «¿COG? ¿compresión? ¿remuestreo? sin propagación de datos»

Lectura relacionada

Prueba Compute hoy

Inicia una instancia de GPU con una plantilla preparada para CUDA (p. ej., Ubuntu 24.04 LTS/CUDA 12.6) o tu propia imagen de GROMACS. Disfrute de una facturación flexible por segundo con plantillas personalizadas y la posibilidad de iniciar, detener y reanudar las sesiones en cualquier momento. ¿No está seguro de los requisitos de FP64? Póngase en contacto con el servicio de asistencia para que le ayuden a seleccionar el perfil de hardware ideal para sus necesidades informáticas.