Transformers es una biblioteca de Hugging Face que proporciona herramientas y APIs para cargar, ejecutar y entrenar modelos preentrenados de procesamiento del lenguaje natural, visión artificial, audio y aplicaciones multimodales.
La biblioteca incluye clases genéricas como AutoTokenizer, AutoModel y pipeline, que permiten utilizar diferentes arquitecturas mediante una interfaz común.
Las versiones disponibles pueden consultarse mediante:
module spider Transformers
Para cargar Transformers 4.39.3:
module load rama0.4 GCC/12.3.0 Transformers/4.39.3
Puede comprobarse la versión cargada mediante:
python -c "import transformers; print(transformers.__version__)"
La salida esperada es:
4.39.3
La información completa del módulo puede consultarse con:
module spider Transformers/4.39.3
El módulo carga, entre otras dependencias:
Puede comprobarse el conjunto completo de módulos cargados mediante:
module list
Transformers se distribuye bajo licencia Apache 2.0.
Cada modelo utilizado con Transformers tiene su propia licencia y sus propias condiciones de uso. Antes de ejecutar o distribuir un modelo debe consultarse su archivo README.md, su tarjeta de modelo y la licencia incluida en el directorio correspondiente.
Transformers es una biblioteca de Python. A diferencia de Ollama, no utiliza un servidor independiente: el modelo se carga directamente desde el programa Python que realiza la inferencia o el entrenamiento.
El flujo general es:
Transformers puede utilizarse tanto en nodos normales de cómputo como en nodos GPU:
Transformers proporciona la interfaz para trabajar con los modelos, pero necesita un backend de aprendizaje automático para ejecutar sus operaciones numéricas. Los backends más habituales son PyTorch, TensorFlow y Flax.
Los ejemplos de este documento utilizan PyTorch.
Después de cargar el módulo debe comprobarse si PyTorch está disponible:
python -c "import torch; print(torch.__version__)"
También puede comprobarse si PyTorch detecta CUDA:
python - <<'PY'
import torch
print("Versión de PyTorch:", torch.__version__)
print("CUDA disponible:", torch.cuda.is_available())
print("Versión CUDA de PyTorch:", torch.version.cuda)
if torch.cuda.is_available():
print("GPU:", torch.cuda.get_device_name(0))
PY
Si aparece:
ModuleNotFoundError: No module named 'torch'
el módulo de Transformers se ha cargado correctamente, pero falta un módulo de PyTorch compatible. Las versiones disponibles pueden consultarse mediante:
module spider PyTorch
Debe cargarse un módulo de PyTorch compatible con la rama y el toolchain utilizados antes de ejecutar ejemplos de inferencia o entrenamiento.
Importante: no debe instalarse otra versión de Transformers con
pipdentro del entorno del módulo salvo que se esté creando deliberadamente un entorno virtual independiente. Mezclar paquetes instalados por EasyBuild con versiones instaladas en~/.localpuede producir incompatibilidades.
Puede comprobarse desde dónde se está importando cada paquete mediante:
python - <<'PY'
import transformers
print("Transformers:", transformers.__version__)
print("Ruta:", transformers.__file__)
try:
import torch
print("PyTorch:", torch.__version__)
print("Ruta:", torch.__file__)
except ImportError:
print("PyTorch no está disponible en el entorno actual")
PY
Los modelos proporcionados por el centro se encuentran bajo:
/lustre/models/
Por ejemplo:
/lustre/models/af3
/lustre/models/deepseek
/lustre/models/dorado
/lustre/models/mistral
/lustre/models/ollama
/lustre/models/qwen
Para consultar los directorios de modelos:
find /lustre/models -mindepth 2 -maxdepth 2 -type d | sort
O puede consultar el listado aquí:
Un modelo de Transformers suele contener archivos como:
config.json
generation_config.json
tokenizer.json
tokenizer_config.json
model.safetensors
Los pesos también pueden estar divididos en varios archivos:
model-00001-of-00003.safetensors
model-00002-of-00003.safetensors
model-00003-of-00003.safetensors
model.safetensors.index.json
Algunos modelos antiguos utilizan pesos PyTorch .bin:
pytorch_model-00001-of-00002.bin
pytorch_model-00002-of-00002.bin
pytorch_model.bin.index.json
Transformers puede cargar modelos desde directorios locales siempre que:
En Drago se recomienda cargar los modelos utilizando sus rutas locales, sin intentar acceder al Hugging Face Hub.
Para forzar el funcionamiento sin conexión:
export TRANSFORMERS_OFFLINE=1
export HF_HUB_OFFLINE=1
Si se utiliza la biblioteca Datasets:
export HF_DATASETS_OFFLINE=1
Además, las llamadas a from_pretrained() deben incluir:
local_files_only=True
Ejemplo:
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained(
"/lustre/models/qwen/Qwen2.5-7b-Instruct",
local_files_only=True,
)
No debe utilizarse únicamente un identificador del Hugging Face Hub como:
AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct")
si los nodos no tienen acceso a Internet, porque Transformers intentará localizar o descargar el modelo desde el Hub.
Debe utilizarse la ruta local:
AutoTokenizer.from_pretrained(
"/lustre/models/qwen/Qwen2.5-7b-Instruct",
local_files_only=True,
)
Por defecto, Hugging Face utiliza un directorio bajo:
$HOME/.cache/huggingface/
Puede definirse explícitamente mediante:
export HF_HOME="$HOME/.cache/huggingface"
mkdir -p "$HF_HOME"
Cuando se utilizan directamente los modelos compartidos de /lustre/models, los pesos no necesitan copiarse a la caché personal.
Antes de cargar todos los pesos puede comprobarse si Transformers reconoce la configuración y el tokenizador.
Archivo comprobar_modelo.py:
from pathlib import Path
from transformers import AutoConfig, AutoTokenizer
MODEL_PATH = Path("/lustre/models/qwen/Qwen2.5-7b-Instruct")
if not MODEL_PATH.is_dir():
raise SystemExit(f"No existe el directorio del modelo: {MODEL_PATH}")
config = AutoConfig.from_pretrained(
MODEL_PATH,
local_files_only=True,
trust_remote_code=False,
)
tokenizer = AutoTokenizer.from_pretrained(
MODEL_PATH,
local_files_only=True,
trust_remote_code=False,
)
print("Directorio:", MODEL_PATH)
print("Arquitectura:", config.architectures)
print("Tipo de modelo:", config.model_type)
print("Clase del tokenizador:", tokenizer.__class__.__name__)
print("Tamaño del vocabulario:", len(tokenizer))
Ejecutarlo mediante:
module load rama0.4 GCC/12.3.0 Transformers/4.39.3
export TRANSFORMERS_OFFLINE=1
export HF_HUB_OFFLINE=1
python comprobar_modelo.py
Esta comprobación carga la configuración y el tokenizador, pero no carga todos los pesos del modelo.
trust_remote_codeAlgunos modelos incluyen código Python propio que no forma parte de la biblioteca Transformers. Esos modelos pueden solicitar:
trust_remote_code=True
Esta opción permite ejecutar código incluido en el directorio o repositorio del modelo. Solo debe activarse después de revisar y confiar en ese código.
Por defecto se recomienda utilizar:
trust_remote_code=False
La inferencia en CPU es posible, pero puede ser muy lenta con modelos de varios miles de millones de parámetros.
Para un modelo grande debe solicitarse suficiente memoria RAM. El siguiente ejemplo muestra una plantilla general; el modelo concreto debe ajustarse a la memoria disponible.
Archivo transformers_cpu.sh:
#!/bin/bash
#SBATCH --job-name=transformers-cpu
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=16
#SBATCH --mem=64G
#SBATCH --time=02:00:00
#SBATCH --partition=generic
#SBATCH --output=transformers-cpu-%j.out
#SBATCH --error=transformers-cpu-%j.err
set -euo pipefail
module load rama0.4 GCC/12.3.0 Transformers/4.39.3
export TRANSFORMERS_OFFLINE=1
export HF_HUB_OFFLINE=1
export TOKENIZERS_PARALLELISM=false
export OMP_NUM_THREADS="${SLURM_CPUS_PER_TASK}"
export OPENBLAS_NUM_THREADS="${SLURM_CPUS_PER_TASK}"
export MKL_NUM_THREADS="${SLURM_CPUS_PER_TASK}"
python generar_cpu.py
Archivo generar_cpu.py:
import os
from pathlib import Path
try:
import torch
except ImportError as exc:
raise SystemExit(
"PyTorch no está disponible. Cargue un módulo PyTorch compatible."
) from exc
from transformers import AutoModelForCausalLM, AutoTokenizer
MODEL_PATH = Path("/lustre/models/qwen/Qwen2.5-7b-Instruct")
THREADS = int(os.environ.get("SLURM_CPUS_PER_TASK", "1"))
torch.set_num_threads(THREADS)
if not MODEL_PATH.is_dir():
raise SystemExit(f"No existe el modelo: {MODEL_PATH}")
tokenizer = AutoTokenizer.from_pretrained(
MODEL_PATH,
local_files_only=True,
trust_remote_code=False,
)
model = AutoModelForCausalLM.from_pretrained(
MODEL_PATH,
local_files_only=True,
trust_remote_code=False,
torch_dtype="auto",
)
model.to("cpu")
model.eval()
messages = [
{
"role": "user",
"content": "Explica brevemente qué es el CSIC.",
}
]
prompt = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True,
)
inputs = tokenizer(
prompt,
return_tensors="pt",
)
with torch.inference_mode():
output_ids = model.generate(
**inputs,
max_new_tokens=128,
do_sample=False,
pad_token_id=tokenizer.eos_token_id,
)
generated_ids = output_ids[:, inputs["input_ids"].shape[1]:]
response = tokenizer.batch_decode(
generated_ids,
skip_special_tokens=True,
)[0]
print(response)
Enviar el trabajo:
sbatch transformers_cpu.sh
Advertencia: Qwen2.5-7B-Instruct es un modelo grande. Aunque puede ejecutarse mediante CPU si hay suficiente memoria, la generación puede ser considerablemente más lenta que en GPU. Para pruebas de CPU se recomienda utilizar un modelo más pequeño si está disponible.
Para la inferencia con modelos grandes se recomienda utilizar la partición GPU.
SLURM configura automáticamente CUDA_VISIBLE_DEVICES. No debe seleccionarse manualmente una GPU que no haya sido asignada al trabajo.
Archivo generar_gpu.py:
from pathlib import Path
try:
import torch
except ImportError as exc:
raise SystemExit(
"PyTorch no está disponible. Cargue un módulo PyTorch compatible con CUDA."
) from exc
from transformers import AutoModelForCausalLM, AutoTokenizer
MODEL_PATH = Path("/lustre/models/qwen/Qwen2.5-7b-Instruct")
if not MODEL_PATH.is_dir():
raise SystemExit(f"No existe el modelo: {MODEL_PATH}")
if not torch.cuda.is_available():
raise SystemExit(
"PyTorch no detecta una GPU CUDA. Compruebe el módulo de PyTorch "
"y los recursos solicitados a SLURM."
)
print("Transformers utilizará:", torch.cuda.get_device_name(0))
tokenizer = AutoTokenizer.from_pretrained(
MODEL_PATH,
local_files_only=True,
trust_remote_code=False,
)
model = AutoModelForCausalLM.from_pretrained(
MODEL_PATH,
local_files_only=True,
trust_remote_code=False,
torch_dtype="auto",
)
model.to("cuda")
model.eval()
messages = [
{
"role": "system",
"content": "Eres un asistente técnico y respondes de forma clara.",
},
{
"role": "user",
"content": "Explica brevemente qué es el CSIC.",
},
]
prompt = tokenizer.apply_chat_template(
messages,
tokenize=False,
add_generation_prompt=True,
)
inputs = tokenizer(
prompt,
return_tensors="pt",
).to(model.device)
with torch.inference_mode():
output_ids = model.generate(
**inputs,
max_new_tokens=128,
do_sample=False,
pad_token_id=tokenizer.eos_token_id,
)
generated_ids = output_ids[:, inputs["input_ids"].shape[1]:]
response = tokenizer.batch_decode(
generated_ids,
skip_special_tokens=True,
)[0]
print(response)
Archivo transformers_gpu.sh:
#!/bin/bash
#SBATCH --job-name=transformers-gpu
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=8
#SBATCH --gres=gpu:1
#SBATCH --mem=64G
#SBATCH --time=02:00:00
#SBATCH --partition=gpu
#SBATCH --output=transformers-gpu-%j.out
#SBATCH --error=transformers-gpu-%j.err
set -euo pipefail
module load rama0.4 GCC/12.3.0 Transformers/4.39.3
# Si PyTorch no está incluido en el entorno, debe cargarse aquí
# un módulo PyTorch compatible con CUDA y con el toolchain utilizado.
export TRANSFORMERS_OFFLINE=1
export HF_HUB_OFFLINE=1
export TOKENIZERS_PARALLELISM=false
export OMP_NUM_THREADS="${SLURM_CPUS_PER_TASK}"
export OPENBLAS_NUM_THREADS="${SLURM_CPUS_PER_TASK}"
export MKL_NUM_THREADS="${SLURM_CPUS_PER_TASK}"
echo "Nodo: $(hostname -s)"
echo "CPU asignadas: ${SLURM_CPUS_PER_TASK}"
echo "GPU visibles: ${CUDA_VISIBLE_DEVICES:-no definido}"
nvidia-smi
python generar_gpu.py
Enviar el trabajo:
sbatch transformers_gpu.sh
Consultar su estado:
squeue -j <jobid>
Revisar la salida:
cat transformers-gpu-<jobid>.out
cat transformers-gpu-<jobid>.err
La memoria necesaria depende de:
Como aproximación, los pesos de un modelo de 7.000 millones de parámetros ocupan:
A estos valores deben añadirse la caché de atención, los buffers temporales y la memoria del propio framework.
Si aparece un error de memoria CUDA:
torch.cuda.OutOfMemoryError: CUDA out of memory
puede intentarse:
max_new_tokens.pipelineLa función pipeline() proporciona una interfaz simplificada para tareas de inferencia.
Algunas tareas disponibles son:
text-generationtext-classificationtoken-classificationquestion-answeringsummarizationtranslationautomatic-speech-recognitionimage-classificationobject-detectionEjemplo general con un modelo local:
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
MODEL_PATH = "/lustre/models/qwen/Qwen2.5-7b-Instruct"
tokenizer = AutoTokenizer.from_pretrained(
MODEL_PATH,
local_files_only=True,
)
model = AutoModelForCausalLM.from_pretrained(
MODEL_PATH,
local_files_only=True,
torch_dtype="auto",
)
generator = pipeline(
task="text-generation",
model=model,
tokenizer=tokenizer,
device=0,
)
result = generator(
"La inteligencia artificial es",
max_new_tokens=64,
do_sample=False,
)
print(result[0]["generated_text"])
En pipeline:
device=-1 utiliza CPU.device=0 utiliza la primera GPU visible.device y device_map.AutoClassLas clases Auto* seleccionan automáticamente la implementación correspondiente a la arquitectura indicada en config.json.
Algunas clases habituales son:
from transformers import AutoConfig
from transformers import AutoTokenizer
from transformers import AutoModel
from transformers import AutoModelForCausalLM
from transformers import AutoModelForSequenceClassification
from transformers import AutoModelForTokenClassification
from transformers import AutoModelForQuestionAnswering
from transformers import AutoModelForSeq2SeqLM
Por ejemplo:
from transformers import AutoTokenizer, AutoModelForCausalLM
model_path = "/lustre/models/qwen/Qwen2.5-7b-Instruct"
tokenizer = AutoTokenizer.from_pretrained(
model_path,
local_files_only=True,
)
model = AutoModelForCausalLM.from_pretrained(
model_path,
local_files_only=True,
)
El sufijo de la clase debe coincidir con la tarea:
AutoModelForCausalLM: generación autoregresiva de texto.AutoModelForSequenceClassification: clasificación de textos.AutoModelForTokenClassification: clasificación por token y reconocimiento de entidades.AutoModelForQuestionAnswering: extracción de respuestas.AutoModelForSeq2SeqLM: traducción, resumen y otras tareas secuencia a secuencia.Para probar un programa en un nodo GPU puede solicitarse una sesión interactiva:
salloc \
--partition=gpu \
--nodes=1 \
--ntasks=1 \
--cpus-per-task=8 \
--gres=gpu:1 \
--mem=64G \
--time=02:00:00
Una vez concedida la reserva:
srun --pty bash
Dentro del nodo:
module load rama0.4 GCC/12.3.0 Transformers/4.39.3
export TRANSFORMERS_OFFLINE=1
export HF_HUB_OFFLINE=1
export TOKENIZERS_PARALLELISM=false
python generar_gpu.py
Al terminar:
exit
Y después debe liberarse la reserva saliendo también de salloc:
exit
Transformers también proporciona APIs para entrenar o ajustar modelos preentrenados.
Los componentes habituales son:
TrainingArguments, que define los parámetros del entrenamiento.Trainer, que coordina el entrenamiento y la evaluación.DataCollator, que construye los lotes.Dataset, normalmente proporcionado por la biblioteca Hugging Face Datasets.Accelerate, para entrenamiento distribuido y gestión de dispositivos.Antes de preparar un trabajo de entrenamiento debe comprobarse qué módulos adicionales están disponibles:
module spider Datasets
module spider Accelerate
module spider PyTorch
El entrenamiento requiere ajustar cuidadosamente:
No debe asumirse que Datasets, Accelerate, PEFT, bitsandbytes o DeepSpeed están incluidos en el módulo de Transformers. Debe comprobarse cada dependencia antes de utilizarla.
ModuleNotFoundError: No module named 'transformers'El módulo no está cargado o Python está utilizando otro entorno.
Comprobar:
module list
which python
python -c "import transformers; print(transformers.__file__)"
ModuleNotFoundError: No module named 'torch'Transformers está disponible, pero falta el backend PyTorch.
Consultar:
module spider PyTorch
y cargar una versión compatible.
OSError: We couldn't connect to 'https://huggingface.co'El código está intentando acceder al Hub.
Utilizar una ruta local y configurar:
export TRANSFORMERS_OFFLINE=1
export HF_HUB_OFFLINE=1
En Python:
local_files_only=True
OSError: ... does not appear to have a file named config.jsonLa ruta no apunta a un directorio de modelo completo o faltan archivos necesarios.
Comprobar:
ls -lah /ruta/al/modelo
KeyError o arquitectura no reconocidaLa arquitectura del modelo puede no estar implementada en Transformers 4.39.3.
Comprobar el tipo declarado:
grep -n '"model_type"' /ruta/al/modelo/config.json
grep -A 3 '"architectures"' /ruta/al/modelo/config.json
Puede ser necesario:
trust_remote_code=True.No debe activarse trust_remote_code=True sin revisar primero el código del modelo.
CUDA disponible: FalseLas causas habituales son:
Comprobar:
echo "$CUDA_VISIBLE_DEVICES"
nvidia-smi
python -c "import torch; print(torch.cuda.is_available(), torch.version.cuda)"
CUDA out of memoryReducir el tamaño del modelo, el contexto, el lote o los tokens generados, o solicitar una GPU con más VRAM.
Puede consultarse la memoria de la GPU mediante:
nvidia-smi
Consultar:
sacct -j <jobid> \
--format=JobID,JobName,State,ExitCode,Elapsed,AllocCPUS,ReqMem,MaxRSS
Revisar también los archivos de salida y error definidos en el sbatch.