GPU para tus proyectos · pago en cripto sin KYC Cómo alquilar
Español
Abrir la consola
Guía práctica / KERNODECK

Perfilar una etapa de PyTorch para saber dónde se va el tiempo

Define primero la etapa que vas a observar, separa carga, transferencia, cálculo y actualización, y luego captura una ventana corta y representativa con torch.profiler. Lee en conjunto la cronología de CPU y las actividades de GPU disponibles. Un tiempo de lanzamiento de Python no es el tiempo de ejecución terminado en el acelerador, y una traza instrumentada no constituye por sí sola un benchmark.

7 min de lectura · Guía para desarrolladores

Elegir una pregunta antes de abrir una traza

Una traza responde mejor a una pregunta precisa: ¿el cálculo espera a los datos, se repite una copia o se llama demasiado a menudo a un operador pequeño? Define la entrada, la salida y las fronteras de tu etapa. Para el entrenamiento, precisa si incluye el backward, la actualización del optimizador y la lectura del batch. Para la inferencia, separa la carga del modelo y la consulta.

Mantén un escenario corto cuya corrección conozcas. Anota formas, batch, precisión, modo del modelo, compilación eventual y origen de los datos. Una entrada simplificada puede ayudar a aislar un comportamiento, pero ya no representa necesariamente la carga completa. Menciona esa diferencia en el informe.

Fija la unidad final: milisegundos por etapa o ejemplos procesados por segundo. Las sumas de eventos no sustituyen al tiempo transcurrido. Compara ventanas que tengan las mismas fronteras de lectura y transferencia.

Distinguir tiempo de CPU, trabajo de GPU y espera

La CPU prepara y lanza operaciones; la GPU puede ejecutarlas más tarde. Un intervalo de Python puede contener, por tanto, lanzamiento, espera o ambos. La documentación CUDA de PyTorch indica que las mediciones precisas deben tener en cuenta este asincronismo, en particular mediante sincronización o eventos adaptados al alcance.

Para una medición de duración de GPU concreta, los eventos CUDA pueden ser adecuados. Para una latencia de extremo a extremo, espera a que termine el trabajo incluido en esa latencia y mide el conjunto de la solicitud. No mezcles estas dos unidades. Una sincronización añadida entre cada operación puede eliminar un solapamiento real y transformar el programa que intentas comprender.

En el perfilador, los tiempos propios de un operador y sus tiempos que incluyen suboperaciones también responden a preguntas distintas. Mira la cronología antes de sumar las filas de la tabla. Actividades simultáneas o anidadas no representan porciones de tiempo transcurrido disjuntas.

Reservar una fase de arranque y una ventana activa

El primer paso puede incluir inicialización, carga o compilación. Decide si tu pregunta se refiere a ese arranque o a una fase ya estabilizada. Conserva ambas observaciones cuando importen para el uso, en lugar de borrar el coste inicial con una media presentada como global.

La función schedule permite distinguir espera, preparación de la recogida y ventana activa. El calentamiento del perfilador no es una prueba de que tu modelo haya alcanzado su régimen estable. Verifica también las formas encontradas y el estado de las cachés. Una aplicación con entradas variables puede encontrar nuevas rutas tras varias iteraciones.

El planning didáctico propuesto más abajo espera una etapa, prepara una y captura dos. Cuatro etapas bastan para explicar el mecanismo, no para establecer una distribución de rendimiento. En una campaña real, elige una ventana justificada y repite la medición fuera del perfilador después del análisis.

Ejemplo propuesto: cuatro etapas con fronteras legibles

El siguiente fragmento no se ha ejecutado. Supone que model, optimizer, loss_fn, loader y device existen, que el modelo está en device y que el cargador proporciona al menos cuatro batches de pares x, y. Realiza actualizaciones: usa un estado experimental previsto para ello, no una sesión cuyos pesos debas preservar.

Las etiquetas separan lectura CPU, transferencia y entrenamiento. El iterador se crea antes de la ventana, lo que excluye parte de su arranque del alcance. El archivo se elige nuevo para evitar sobrescribir una traza. El ejemplo rechaza una recolección GPU no disponible en lugar de presentar discretamente una traza CPU como un análisis GPU.

La señal step() avanza la planificación tras cada etapa. La receta oficial describe este vínculo entre iteraciones y recolección. En una pila ROCm, el dispositivo de PyTorch sigue llamándose cuda; la disponibilidad de la recolección del acelerador depende, no obstante, del build y de sus herramientas. Verifica las actividades realmente presentes en el resultado.

Captura didáctica de una ventana corta, no ejecutada
from pathlib import Path
import torch
from torch.profiler import (
    profile, schedule, record_function,
    ProfilerActivity, supported_activities,
)

trace = Path("trace-etape.json")
if trace.exists():
    raise FileExistsError("Choisissez un nouveau nom de trace")
activities = [ProfilerActivity.CPU]
if device.type == "cuda":
    if ProfilerActivity.CUDA not in supported_activities():
        raise RuntimeError("Collecte GPU indisponible dans ce build")
    activities.append(ProfilerActivity.CUDA)
iterator = iter(loader)
model.train()

with profile(
    activities=activities,
    schedule=schedule(wait=1, warmup=1, active=2, repeat=1),
    record_shapes=False, profile_memory=False, with_stack=False,
    on_trace_ready=lambda p: p.export_chrome_trace(str(trace)),
) as prof:
    for _ in range(4):
        with record_function("lecture_batch_cpu"):
            x, y = next(iterator)
        with record_function("transfert"):
            x, y = x.to(device), y.to(device)
        with record_function("entrainement"):
            optimizer.zero_grad(set_to_none=True)
            loss = loss_fn(model(x), y)
            loss.backward()
            optimizer.step()
        prof.step()
print(prof.key_averages().table(
    sort_by="self_cpu_time_total", row_limit=8,
))

Convertir una observación en una hipótesis verificable

Empieza por la ventana activa y comprueba que aparecen las etiquetas esperadas. Examina después los espacios entre actividades, las copias y las repeticiones. Una larga espera en lectura_batch_cpu orienta hacia el pipeline de entrada; no mide directamente el almacenamiento. Una copia frecuente invita a examinar la ubicación de los tensores, sin probar que sea inútil.

Formula una sola hipótesis y luego propón una modificación controlada. Por ejemplo, si una constante se reconstruye y se transfiere en cada etapa, comprueba si su tiempo de vida puede abarcar varias etapas sin cambiar el resultado. Si un operador parece dominante, inspecciona sus formas y el número de llamadas antes de buscar un reemplazo.

Las líneas de abajo son lecturas posibles, no constataciones extraídas de una traza ejecutada. No se anuncia ninguna duración ni aceleración. La conclusión útil es un experimento siguiente que pueda confirmar o refutar la causa propuesta.

Desplaza la tabla para leer todas las columnas.
Interpretaciones didácticas que debes verificar en tu propia traza
Observación posibleHipótesisComprobación siguiente
GPU sin actividad durante la lecturaEl pipeline de entrada no sigue el ritmoMismo cálculo con batch ya preparado
Copias recurrentes de una constanteUbicación o tiempo de vida inadecuadosMover una vez, verificar las salidas
Muchos lanzamientos pequeñosTrabajo fragmentadoExaminar agrupación y coste global
Un operador largoForma o algoritmo determinantesComparar el mismo operador y sus entradas

Limitar el coste y la información de la instrumentación

Empieza con una recolección corta y pocas opciones. Activa las formas, las pilas o la memoria solo si una pregunta lo requiere. La API de PyTorch precisa que esta información añade un coste; la recolección de las formas puede incluso retener referencias a los tensores. Un perfil detallado puede, por tanto, cambiar las duraciones o el uso de memoria del programa.

Una traza puede contener nombres de operadores, formas y, según las opciones, rutas de código. Inspecciónala antes de compartirla. Una etiqueta de zona debe describir la etapa sin incluir correos, tokens, rutas privadas ni contenido de entrada. Elige un visor de trazas adecuado para tu entorno y mantén la recolección bajo tu control.

Si los eventos GPU esperados están ausentes, no rellenes sus tiempos con cero. Indica que no se observaron y revisa el soporte de la recolección. Una ausencia de evento en la herramienta no es prueba de ausencia de cálculo.

Validar la optimización fuera del perfilador

Parte del mismo estado relevante y compara la corrección antes y después de la modificación. En entrenamiento, un paso adicional cambia los pesos; dos capturas lanzadas sucesivamente no constituyen necesariamente una comparación equivalente. Conserva el código, los parámetros y el punto de partida para poder explicar la diferencia.

Mide después el escenario sin recolección detallada, con el mismo calentamiento y varias pasadas. Reporta el alcance, los valores brutos y su dispersión. Una mejora local puede desaparecer en el bucle completo o degradar la calidad: ambas deben permanecer en la decisión.

Por último, usa las observaciones para precisar los recursos realmente necesarios. Una traza de tu equipo no clasifica las ofertas de Kernodeck ni prueba el procesador anfitrión ni la red de un servidor alquilado. La comparación de GPU exige una carga, unas condiciones y unos resultados comparables en los recursos en cuestión.

Tus preguntas

¿El mayor tiempo de CPU indica el operador GPU más lento?

No. Puede incluir lanzamiento, procesamiento del lado del anfitrión o espera. Observa los eventos GPU y su cronología cuando la recolección los proporcione. La tabla ordenada por tiempo de CPU solo responde a esa perspectiva.

¿Debo sumar todos los tiempos CUDA de la tabla?

No para obtener automáticamente la duración total. Las actividades pueden solaparse y los eventos pueden estar anidados. Define una ventana de tiempo transcurrido y usa la traza para explicar su contenido.

¿Bastan dos pasos activos para publicar un rendimiento?

No. El pequeño planning propuesto ilustra la API. Un resultado aprovechable requiere una ventana representativa, repeticiones, un calentamiento explícito y una medición final sin el sobrecoste de la recolección detallada.

¿Puede una traza de CPU diagnosticar ROCm?

Puede arrojar luz sobre el trabajo del lado del anfitrión, pero no sustituye a las actividades GPU. PyTorch también emplea el nombre cuda en ROCm; verifica el backend, las actividades compatibles y las realmente registradas antes de interpretar la traza.