> ## Documentation Index
> Fetch the complete documentation index at: https://docs.comfy.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Trabajar con torch.Tensor

> Aprende los básicos de torch.Tensor para nodos personalizados de ComfyUI: formas, squeeze/unsqueeze, notación y operaciones elemento a elemento.

## pytorch, tensores y torch.Tensor

Todo el procesamiento numérico central en Comfy lo hace [pytorch](https://pytorch.org/). Si tus nodos personalizados van a meterse en las entrañas de Stable Diffusion, necesitarás familiarizarte con esta librería, algo que queda muy fuera del alcance de esta introducción.

Sin embargo, muchos nodos personalizados tendrán que manipular imágenes, latents y máscaras, y cada uno de ellos se representa internamente como `torch.Tensor`, así que te conviene guardar en marcadores la
[documentación de torch.Tensor](https://pytorch.org/docs/stable/tensors.html).

### ¿Qué es un tensor?

`torch.Tensor` representa un tensor, que es la generalización matemática de un vector o una matriz a cualquier número de dimensiones.
El *rango* de un tensor es el número de dimensiones que tiene (así, un vector tiene *rango* 1 y una matriz *rango* 2); su *forma* describe el
tamaño de cada dimensión.

Así, una imagen RGB (de alto H y ancho W) podría concebirse como tres arreglos (uno por cada canal de color), cada uno de H x W,
que se podría representar como un tensor con *forma* `[H,W,3]`. En Comfy las imágenes casi siempre vienen en un lote (aunque el lote
solo contenga una imagen). `torch` siempre coloca la dimensión del lote primero, así que las imágenes de Comfy tienen *forma* `[B,H,W,3]`, generalmente
escrita como `[B,H,W,C]`, donde C significa Canales.

### squeeze, unsqueeze y reshape

Si un tensor tiene una dimensión de tamaño 1 (conocida como dimensión colapsada), equivale al mismo tensor con esa dimensión eliminada
(un lote con 1 imagen es simplemente una imagen). Eliminar esa dimensión colapsada se conoce como squeeze, e
insertar una se conoce como unsqueeze.

> [!WARNING]
>
> Parte del código de torch, y algunos autores de nodos personalizados, devolverán un tensor con la dimensión comprimida cuando una dimensión está colapsada,
> como cuando un lote tiene un solo miembro. ¡Esta es una causa común de errores!

Representar los mismos datos con una forma diferente se conoce como reshape. A menudo esto requiere que conozcas
la estructura de datos subyacente, así que ¡manipúlalo con cuidado!

### Notación importante

`torch.Tensor` admite la mayor parte de la notación de slicing de Python, la iteración y otras operaciones comunes similares a listas. Un tensor
también tiene un atributo `.shape` que devuelve su tamaño como un `torch.Size` (que es una subclase de `tuple` y se puede
tratar como tal).

Hay otras piezas de notación importantes que verás a menudo (varias son notación estándar de Python menos común,
que se ve mucho más cuando se trabaja con tensores)

* `torch.Tensor` admite el uso de `None` en la notación de slicing
  para indicar la inserción de una dimensión de tamaño 1.

* `:` se usa con frecuencia al hacer slicing de un tensor; simplemente significa "mantener toda la dimensión".
  Es como usar `a[start:end]` en Python, pero omitiendo el punto inicial y el punto final.

* `...` representa "la totalidad de un número no especificado de dimensiones". Así, `a[0, ...]` extraería el primer
  elemento de un lote sin importar el número de dimensiones.

* en los métodos que requieren que se pase una forma, esta suele pasarse como una `tuple` de las dimensiones, en
  la cual a una sola dimensión se le puede dar el tamaño `-1`, lo que indica que el tamaño de esa dimensión debe
  calcularse a partir del tamaño total de los datos.

```python theme={null}
>>> a = torch.Tensor((1,2))
>>> a.shape
torch.Size([2])
>>> a[:,None].shape 
torch.Size([2, 1])
>>> a.reshape((1,-1)).shape
torch.Size([1, 2])
```

### Operaciones elemento a elemento

Muchas operaciones binarias en `torch.Tensor` (incluidos '+', '-', '\*', '/' y '==') se aplican elemento a elemento (se aplican de forma independiente a cada elemento).
Los operandos deben ser *o bien* dos tensores de la misma forma, *o bien* un tensor y un escalar. Así:

```python theme={null}
>>> import torch
>>> a = torch.Tensor((1,2))
>>> b = torch.Tensor((3,2))
>>> a*b
tensor([3., 4.])
>>> a/b
tensor([0.3333, 1.0000])
>>> a==b
tensor([False,  True])
>>> a==1
tensor([ True, False])
>>> c = torch.Tensor((3,2,1)) 
>>> a==c
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: The size of tensor a (2) must match the size of tensor b (3) at non-singleton dimension 0
```

### Veracidad de un tensor

> [!WARNING]
>
> El valor de "veracidad" de un tensor no es el mismo que el de las listas de Python.

Quizá conozcas el valor de verdad de una lista de Python: `True` para cualquier lista no vacía y `False` para `None` o `[]`.
En cambio, un `torch.Tensor` (con más de un elemento) no tiene un valor de verdad definido. En su lugar necesitas usar
`.all()` o `.any()` para combinar los valores de verdad elemento a elemento:

```python theme={null}
>>> a = torch.Tensor((1,2))
>>> print("yes" if a else "no")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
RuntimeError: Boolean value of Tensor with more than one value is ambiguous
>>> a.all()
tensor(False)
>>> a.any()
tensor(True)
```

Esto también significa que debes usar `if a is not None:` y no `if a:` para determinar si una variable de tensor ha sido asignada.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.