HFL — Arquitectura Completa

Run HuggingFace Models Locally Like Ollama
v0.1.0 Python ≥3.10 Licencia HRUL-1.0 Autor: Gabriel Galán Pelayo Build: Hatchling

1. Visión General y Propósito

HFL (HuggingFace Local) es una herramienta CLI y servidor API que permite descargar, gestionar y ejecutar modelos de inteligencia artificial de HuggingFace Hub directamente en la máquina local del usuario. Su diseño aspira a ser un drop-in replacement de Ollama, pero conectado al ecosistema de HuggingFace con más de 500.000 modelos.

🎯

Problema que Resuelve

Los usuarios necesitan ejecutar LLMs localmente sin depender de APIs en la nube. Ollama resuelve esto pero con un catálogo limitado. HFL conecta directamente con HuggingFace Hub, ofreciendo acceso al catálogo más grande de modelos open-weight del mundo, con descarga, conversión automática a GGUF y ejecución local.

🏗️

Filosofía de Diseño

Modularidad extrema con lazy imports, compatibilidad API dual (OpenAI + Ollama), cumplimiento legal riguroso (licencias, privacidad, EU AI Act), y soporte multi-backend (llama.cpp, Transformers, vLLM) con selección automática según el formato del modelo y el hardware disponible.

2. Stack Tecnológico

Core

Python ≥3.10Lenguaje base
typer ≥0.12Framework CLI
rich ≥13.0Output con estilo
pydantic ≥2.10Validación de datos API
pyyaml ≥6.0Parsing de configuración

API Server

fastapi ≥0.115Framework web async
uvicorn ≥0.32Servidor ASGI
sse-starlette ≥2.0Server-Sent Events
httpx ≥0.28HTTP client async

HuggingFace

huggingface-hub ≥0.27API de HF Hub

Extras Opcionales

llama-cpp-pythonBackend GGUF
transformers+torchBackend GPU nativo
vllmBackend producción
ggufConversión de formato

3. Estructura de Archivos del Proyecto

hfl/
├── pyproject.toml           — Definición del paquete, deps, scripts, herramientas
├── hfl.spec                 — PyInstaller spec para ejecutable standalone
├── LICENSE                  — HRUL v1.0 (licencia propia)
├── LICENSE-DEPENDENCIES.md  — Licencias de todas las dependencias
├── PRIVACY.md               — Política de privacidad
├── NOTICE-EU-AI-ACT.md     — Cumplimiento EU AI Act
├── DISCLAIMER.md            — Exención de responsabilidad
├── README.md                — Documentación principal
├── README.es.md             — Documentación principal (español)
├── LICENSE-FAQ.md            — Preguntas frecuentes sobre la licencia HRUL
├── CONTRIBUTING.md           — Guía de contribución
├── CODE_OF_CONDUCT.md        — Código de conducta (Contributor Covenant 2.1)
├── CHANGELOG.md              — Historial de cambios (Keep a Changelog)
├── SECURITY.md               — Política de seguridad
│
├── src/hfl/                 — CÓDIGO FUENTE PRINCIPAL
│   ├── __init__.py          — Versión del paquete (0.1.0)
│   ├── config.py            — HFLConfig dataclass — configuración global
│   ├── exceptions.py        — Jerarquía completa de excepciones
│   ├── events.py            — EventBus para pub/sub interno
│   ├── metrics.py           — Métricas de rendimiento
│   ├── plugins.py           — Sistema de plugins con entry_points
│   ├── security.py          — Sanitización y validación de seguridad
│   ├── validators.py        — Validadores de datos comunes
│   ├── logging_config.py    — Configuración centralizada de logging
│   │
│   ├── core/                — NÚCLEO DEL SISTEMA
│   │   ├── __init__.py
│   │   ├── container.py     — Contenedor DI con Singleton thread-safe
│   │   ├── observability_setup.py — Setup de listeners de observabilidad
│   │   └── tracing.py       — Request tracing con IDs
│   │
│   ├── cli/                 — INTERFAZ DE LÍNEA DE COMANDOS
│   │   ├── __init__.py
│   │   ├── main.py          — 12 comandos: pull, run, serve, list, search, rm, inspect, alias, login, logout, version, compliance-report
│   │   └── commands/        — Comandos modularizados
│   │       └── _utils.py    — Utilidades compartidas CLI
│   │
│   ├── api/                 — SERVIDOR REST API
│   │   ├── __init__.py
│   │   ├── server.py        — FastAPI app, CORS, disclaimer, lifespan
│   │   ├── state.py         — ServerState con async locks para LLM/TTS
│   │   ├── streaming.py     — SSE streaming helpers
│   │   ├── model_loader.py  — Carga dinámica de modelos
│   │   ├── helpers.py       — ensure_llm_loaded, ensure_tts_loaded
│   │   ├── errors.py        — Manejo centralizado de errores HTTP
│   │   ├── middleware.py    — Logging privacy-safe
│   │   ├── rate_limit.py    — Rate limiting por IP/token
│   │   ├── routes_openai.py — /v1/chat/completions, /v1/completions, /v1/models
│   │   ├── routes_native.py — /api/generate, /api/chat, /api/tags (Ollama-compatible)
│   │   ├── routes_tts.py    — /v1/audio/speech, /api/tts (TTS endpoints)
│   │   ├── routes_health.py — /health, /ready, /live (healthchecks)
│   │   ├── routes_metrics.py — /metrics (Prometheus + JSON)
│   │   ├── exception_handlers.py — Manejo global de excepciones HFLError
│   │   └── timeout.py       — Decorator @with_timeout + timeout configurable
│   │
│   ├── engine/              — MOTORES DE INFERENCIA
│   │   ├── __init__.py
│   │   ├── base.py          — InferenceEngine + AudioEngine ABCs + dataclasses
│   │   ├── selector.py      — Selección automática de backend LLM/TTS
│   │   ├── llama_cpp.py     — LlamaCppEngine (GGUF, CPU/GPU)
│   │   ├── transformers_engine.py — TransformersEngine (safetensors, GPU)
│   │   ├── vllm_engine.py   — VLLMEngine (producción GPU)
│   │   ├── bark_engine.py   — BarkEngine (TTS via transformers)
│   │   ├── coqui_engine.py  — CoquiEngine (TTS XTTS-v2)
│   │   ├── async_wrapper.py — Wrapper sync→async para engines
│   │   ├── model_pool.py    — Pool de modelos con LRU eviction
│   │   ├── dependency_check.py — Verificación de dependencias opcionales
│   │   ├── failover.py      — FailoverEngine (multi-engine retry con sticky routing)
│   │   ├── memory.py        — Tracking de memoria RAM/GPU en tiempo real
│   │   ├── observability.py — Métricas de rendimiento del engine
│   │   └── prompt_builder.py — Formatos de prompt + escape de delimitadores
│   │
│   ├── hub/                 — INTEGRACIÓN HUGGINGFACE
│   │   ├── __init__.py
│   │   ├── auth.py          — Autenticación y tokens
│   │   ├── client.py        — Cliente HTTP para HF Hub
│   │   ├── downloader.py    — Descarga con resume y rate limiting
│   │   ├── license_checker.py — Clasificación de licencias (5 niveles)
│   │   └── resolver.py      — Resolución inteligente de modelos
│   │
│   ├── models/              — MODELOS DE DATOS
│   │   ├── __init__.py
│   │   ├── manifest.py      — ModelManifest — metadata completa
│   │   ├── provenance.py    — ConversionRecord + ProvenanceLog
│   │   ├── registry.py      — ModelRegistry — inventario local JSON
│   │   └── backends/        — Backends de almacenamiento (File + SQLite)
│   │
│   ├── converter/           — CONVERSIÓN DE FORMATOS
│   │   ├── __init__.py
│   │   ├── formats.py       — ModelFormat + ModelType enums
│   │   └── gguf_converter.py — GGUFConverter — conversión + cuantización
│   │
│   ├── utils/               — UTILIDADES TRANSVERSALES
│   │   ├── __init__.py
│   │   ├── circuit_breaker.py — Circuit breaker para resiliencia
│   │   └── retry.py         — Retry con exponential backoff
│   │
│   └── i18n/                — INTERNACIONALIZACIÓN
│       ├── __init__.py      — t(), get_language(), set_language()
│       └── locales/         — Archivos de traducción
│           ├── en.json      — Traducciones en inglés
│           └── es.json      — Traducciones en español
│
├── docs/                    — DOCUMENTACIÓN
│   ├── adr/                 — Architecture Decision Records
│   │   ├── 0001-singleton-pattern.md
│   │   ├── 0002-async-api-sync-engines.md
│   │   ├── 0003-gguf-default-format.md
│   │   ├── 0004-ollama-compatibility.md
│   │   ├── 0005-license-classification.md
│   │   └── 0006-rate-limiting-strategy.md
│   └── *.html               — Documentación arquitectura
│
└── tests/                   — SUITE DE TESTS (80+ archivos, 90%+ cobertura)
    ├── conftest.py          — Fixtures compartidas
    ├── test_api*.py         — Tests API (5 archivos)
    ├── test_cli*.py         — Tests CLI (4 archivos)
    ├── test_engine*.py      — Tests engines (8 archivos)
    ├── test_hub*.py         — Tests HF Hub (5 archivos)
    ├── test_i18n*.py        — Tests i18n (4 archivos)
    └── test_*.py            — Tests unitarios y de integración
│
├── .github/                   — INFRAESTRUCTURA GITHUB
│   ├── workflows/
│   │   ├── ci.yml             — CI: lint + test + type-check (Python 3.10/3.11/3.12)
│   │   ├── pages.yml          — Deploy docs a GitHub Pages
│   │   ├── build-executables.yml — Build ejecutables multiplataforma
│   │   ├── lint.yml           — Linting con ruff
│   │   ├── test.yml           — Tests con pytest
│   │   ├── security.yml       — Auditoría de seguridad
│   │   └── license-check.yml  — Verificación de licencias
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yml     — Template para reportes de bugs
│   │   └── feature_request.yml — Template para solicitudes de features
│   └── PULL_REQUEST_TEMPLATE.md — Template de PR con checklist de compliance

4. Diagrama de Arquitectura General

Arquitectura de Alto Nivel — HFL v0.1.0
CLI (typer + rich) pull run serve list search rm inspect alias login logout version cli/main.py — Punto de entrada: hfl.cli.main:app API Server (FastAPI + Uvicorn) OpenAI Compatible Ollama Compatible Middleware: CORS + Disclaimer + Privacy Logger Consumidores Terminal (CLI interactivo) OpenAI SDK / httpx / curl Apps Ollama (Open WebUI, etc.) Hub (HuggingFace Integration) resolver.py downloader.py license_checker.py auth.py Conexión: huggingface_hub API Engine (Motores de Inferencia) LlamaCpp GGUF CPU/GPU Transformers safetensors GPU vLLM Producción GPU selector.py → Auto-selección por formato + hardware ABC: InferenceEngine (base.py) Models (Datos y Registro) manifest.py registry.py provenance.py Persistencia: ~/.hfl/models.json ~/.hfl/provenance.json Converter (Conversión de Formatos) formats.py gguf_converter.py safetensors → FP16 GGUF → Quantized GGUF Config + Exceptions (Núcleo) config.py (HFLConfig) exceptions.py (15 tipos) Home: ~/.hfl | Puerto: 11434 (Ollama compat) HuggingFace Hub (Externo) huggingface.co API 500.000+ modelos Gated models + Licencias Sistema de Archivos Local — ~/.hfl/ models/ Archivos de modelos (GGUF, safetensors) models.json Registro de modelos locales provenance.json Log de conversiones cache/ + tools/llama.cpp Cache HF + herramientas compiladas

5. Módulo config — Configuración Central

Archivo: src/hfl/config.py

Contiene la clase HFLConfig (dataclass) que define toda la configuración global de la aplicación. Se instancia una vez como singleton (config = HFLConfig()) al importar el módulo, y se llama a ensure_dirs() para crear la estructura de directorios.

PropiedadTipoDefaultDescripción
home_dirPath~/.hflDirectorio raíz. Override con HFL_HOME env var
models_dirPath (prop)~/.hfl/modelsAlmacenamiento de modelos descargados
cache_dirPath (prop)~/.hfl/cacheCaché temporal de HuggingFace
registry_pathPath (prop)~/.hfl/models.jsonRegistro de modelos (inventario local)
llama_cpp_dirPath (prop)~/.hfl/tools/llama.cppHerramientas de conversión compiladas
hoststr127.0.0.1Dirección del servidor API. Override con HFL_HOST
portint11434Puerto (igual que Ollama para compatibilidad). Override con HFL_PORT
default_ctx_sizeint4096Tokens de contexto por defecto
default_n_gpu_layersint-1Capas GPU (-1 = todas)
hf_tokenstr|Noneenv HF_TOKENToken de autenticación (solo memoria, nunca persiste)
rate_limit_enabledbooltrueHabilitar rate limiting. Override con HFL_RATE_LIMIT_ENABLED
rate_limit_requestsint60Peticiones permitidas por ventana. Override con HFL_RATE_LIMIT_REQUESTS
rate_limit_windowint60Ventana de tiempo en segundos. Override con HFL_RATE_LIMIT_WINDOW

Adicionalmente, SLOConfig define los Service Level Objectives del servidor: availability target, latencia P50/P95/P99.

6. Módulo cli — Interfaz de Línea de Comandos

Archivo: src/hfl/cli/main.py (~870 líneas)

Framework: Typer + Rich. Entry point registrado en pyproject.toml como hfl = "hfl.cli.main:app"

ComandoDescripciónOpciones Clave
hfl pull <modelo>Descarga modelo desde HF Hub--quantize Q4_K_M, --format auto|gguf|safetensors, --alias, --skip-license
hfl run <modelo>Chat interactivo en terminal--backend auto|llama-cpp|transformers|vllm, --ctx, --system, --verbose
hfl serveServidor API REST--host, --port, --model (pre-carga), --api-key (autenticación)
hfl listLista modelos locales con tabla RichMuestra nombre, alias, formato, cuantización, licencia (coloreada por riesgo), tamaño
hfl search <query>Búsqueda paginada interactiva en HF Hub--gguf, --max-params, --min-params, --sort, --page-size
hfl rm <modelo>Elimina modelo con confirmaciónBorra archivos + entrada del registro
hfl inspect <modelo>Detalle completo (panel Rich)Muestra metadata, licencia, restricciones, timestamps
hfl alias <modelo> <alias>Asigna alias cortoPermite referir modelos por nombres simples
hfl loginConfigura token HF--token o interactivo. Verifica con whoami()
hfl logoutElimina token guardadoUsa huggingface_hub.logout()
hfl versionMuestra versión + licencia
hfl compliance-reportInforme de cumplimiento legal (JSON/Markdown)
Signal Handling: El comando run maneja Ctrl+C durante el streaming de tokens de forma limpia, preservando la respuesta parcial.

Funciones Auxiliares del CLI

_format_size() convierte bytes a formato legible. _get_key() lee una tecla sin Enter (raw terminal). _extract_params_from_name() extrae parámetros del nombre (regex: "70b", "7b", "1.5b"). _estimate_model_size() estima tamaño en disco según parámetros y cuantización. _display_model_row() renderiza una fila de resultado de búsqueda. _get_params_value() extrae el valor numérico para filtrado.

7. Módulo hub — Integración con HuggingFace

resolver.py — Resolución Inteligente

Clase ResolvedModel (dataclass) con: repo_id, revision, filename, format, quantization.

La función resolve() soporta tres formatos de entrada:

1. org/modelo → repo directo en HF

2. org/modelo:Q4_K_M → repo con cuantización estilo Ollama

3. nombre-modelo → búsqueda por nombre (top 5 por descargas)

Tras resolver, detecta si el repo tiene archivos GGUF (prefiere _select_gguf() con prioridad Q4_K_M > Q5_K_M > Q4_K_S), safetensors, o pytorch.

downloader.py — Descarga con Progreso

Función principal pull_model(resolved). Para GGUF descarga archivo individual con hf_hub_download(). Para safetensors descarga snapshot completo con snapshot_download() filtrando: *.safetensors, config.json, tokenizer*.json, tokenizer.model.

Implementa rate limiting (0.5s entre llamadas API) y User-Agent identificativo (hfl/0.1.0) para cumplir con ToS de HuggingFace.

auth.py — Autenticación

get_hf_token() obtiene token con prioridad: 1) env var HF_TOKEN, 2) token guardado por huggingface_hub.

ensure_auth(repo_id) verifica acceso al repo. Si falla y no hay token, solicita interactivamente. Respeta el sistema de gating de HF: NO bypasea la aceptación de licencias de modelos gated.

license_checker.py — Clasificación de Licencias

Enum LicenseRisk: PERMISSIVE, CONDITIONAL, NON_COMMERCIAL, RESTRICTED, UNKNOWN.

Diccionario LICENSE_CLASSIFICATION con ~20 licencias conocidas. Diccionario LICENSE_RESTRICTIONS con restricciones específicas por familia (Llama: 700M MAU, attribution, etc.).

check_model_license() consulta la API de HF, clasifica el riesgo, y devuelve LicenseInfo. require_user_acceptance() presenta un panel Rich con la licencia y requiere confirmación explícita para licencias no permisivas.

8. Módulo models — Datos y Registro

ModelManifest (manifest.py)

Dataclass que almacena la metadata completa de cada modelo descargado. Es la unidad fundamental de información en el sistema.

CampoTipoPropósito
name, repo_idstrIdentificación (nombre corto + repo HF)
aliasstr|NoneNombre personalizado por el usuario
local_path, formatstrUbicación y tipo (gguf/safetensors/pytorch)
size_bytes, quantizationint, strTamaño en disco + nivel Q
architecture, parameters, context_lengthstr, str, intCaracterísticas del modelo
license, license_name, license_urlstrInformación legal (R1)
license_restrictions, gated, license_accepted_atlist, bool, strRestricciones y aceptación
gpai_classification, training_flopsstrEU AI Act (R4)
created_at, last_usedstrTimestamps

ModelRegistry (registry.py)

Gestiona el inventario local. Persiste a ~/.hfl/models.json como array JSON. Operaciones: add() (evita duplicados), get() (busca por name, alias, o repo_id), set_alias(), list_all() (ordenado por fecha), remove().

ProvenanceLog (provenance.py)

Log inmutable de conversiones en ~/.hfl/provenance.json. Cada ConversionRecord documenta: origen (repo, formato, revisión), destino (formato, path, cuantización), herramienta usada (llama.cpp + versión), licencia original, y timestamps. Sirve para trazabilidad legal y auditoría de cumplimiento (R3).

9. Módulo engine — Motores de Inferencia

Jerarquía de Clases — Engine
«ABC» InferenceEngine + load(path, **kwargs) + unload() / generate() / generate_stream() + chat() / chat_stream() / model_name / is_loaded LlamaCppEngine GGUF | CPU+Metal+CUDA+Vulkan Flash Attention, auto chat format TransformersEngine safetensors | GPU CUDA BitsAndBytes 4bit/8bit, TextIteratorStreamer VLLMEngine Producción GPU | NVIDIA CUDA PagedAttention, batching continuo selector.py → GGUF→LlamaCpp | CUDA+safetensors→Transformers | fallback→LlamaCpp Dataclasses ChatMessage(role, content) GenerationConfig(temp, top_p...) GenerationResult(text, tokens...)

LlamaCppEngine

Backend principal. Usa llama-cpp-python. Parámetros: n_ctx, n_gpu_layers (-1=todas), n_threads (0=auto), flash_attn, chat_format (auto-detect). Incluye supresión de stderr para silenciar logs de Metal/CUDA cuando verbose=False. Genera resultados con métricas: tokens/s, prompt tokens, stop reason.

TransformersEngine

Usa modelos en formato nativo con GPU. Soporte cuantización dinámica: 4bit (NF4 double quant via BitsAndBytes) y 8bit. Streaming via TextIteratorStreamer en thread separado. Usa apply_chat_template() del tokenizer o fallback Llama-style.

VLLMEngine

EXPERIMENTAL Backend para producción GPU. Wrappea vllm.LLM con SamplingParams. Streaming real con AsyncLLMEngine, con fallback sincrono para compatibilidad. Requiere GPU NVIDIA con CUDA.

FailoverEngine

Motor con multiple backends y sticky routing — reintenta automaticamente con el siguiente engine disponible si uno falla.

Model Pool & Memory

Pool de modelos con espera no recursiva (bounded polling), evitando stack overflow con multiples cargas concurrentes. Tracking de memoria RAM y GPU en tiempo real mediante psutil y GPUtil.

Selector Automático (selector.py)

Lógica de decisión en select_engine(model_path, backend):

Modelo GGUF? → Sí → LlamaCppEngine
GPU CUDA disponible? → Sí → TransformersEngine → ImportError → Fallback: LlamaCppEngine
Sin GPU? LlamaCppEngine (necesitará conversión previa)

Todos los imports son lazy (_get_llama_cpp_engine(), etc.) para no requerir todas las dependencias instaladas.

10. Módulo converter — Conversión de Formatos

formats.py — Detección de Formatos

Enum ModelFormat: GGUF, SAFETENSORS, PYTORCH, UNKNOWN. La función detect_format(path) inspecciona extensiones (.gguf, .safetensors, .pt/.pth/.bin) tanto en archivos individuales como en directorios (rglob). find_model_file() localiza el archivo principal del modelo.

gguf_converter.py — Conversión a GGUF

Clase GGUFConverter con pipeline de dos pasos:

safetensors/pytorch → Paso 1 → convert_hf_to_gguf.py (FP16) → Paso 2 → llama-quantize (Q4_K_M) GGUF final

ensure_tools() auto-instala llama.cpp si no existe: git clone → cmake build → pip install requirements. check_model_convertibility() valida que el modelo sea convertible (rechaza LoRA adapters, modelos de imagen, modelos sin config.json).

CuantizaciónBits/pesoCalidadCaso de Uso
Q2_K~2.5~80%Extrema compresión
Q3_K_M~3.5~87%Poca RAM
Q4_K_M~4.5~92%DEFAULT — mejor balance
Q5_K_M~5.0~96%Alta calidad
Q6_K~6.5~97%Premium
Q8_0~8.0~98%+Máxima calidad cuantizada
F1616.0100%Sin cuantización

11. Módulo api — Servidor REST

Endpoints y Compatibilidad API
FastAPI Server (server.py) RequestLogger → APIKey → RateLimit → Disclaimer → CORS OpenAI Compatible (routes_openai.py) POST /v1/chat/completions Chat con streaming SSE (text/event-stream) POST /v1/completions Text completion con streaming GET /v1/models — Lista modelos disponibles Schemas: ChatCompletionRequest, CompletionRequest Helpers: _ensure_model_loaded() → auto-carga Streaming: _stream_chat(), _stream_completion() Formato: SSE data: {...}\n\n + data: [DONE] Ollama Compatible (routes_native.py) POST /api/generate Generación texto con streaming NDJSON POST /api/chat Chat multi-turno con streaming NDJSON GET /api/tags + /api/version + HEAD / Schemas: GenerateRequest, ChatRequest Streaming: application/x-ndjson Compatible con: Open WebUI, Chatbox, etc. Helper: _options_to_config() para parámetros

ServerState

Clase con engine (InferenceEngine activo), current_model (ModelManifest cargado) y api_key (str|None para autenticación). Instanciada como singleton global. El lifespan del servidor hace cleanup al cerrar.

Middleware Stack

Orden de ejecución Starlette (outer → inner): RequestLogger → APIKey → RateLimit (condicional) → Disclaimer → CORS. El orden de add_middleware() es inverso: CORS, Disclaimer, RateLimit, APIKey, RequestLogger. APIKey se ejecuta ANTES de RateLimit, de modo que las peticiones no autenticadas son rechazadas sin consumir tokens del rate limiter.

CORSMiddleware — Permite todas las orígenes, métodos y headers (desarrollo local).

DisclaimerMiddleware — Añade header X-AI-Disclaimer a respuestas de endpoints de generación AI (R9).

RateLimitMiddleware — Limitación de tasa por IP, configurable vía env vars. Soporta rate limiting por modelo.

APIKeyMiddleware — Autenticación opcional via --api-key. Soporta Authorization: Bearer <key> y X-API-Key: <key>. Endpoints públicos (/health, /) exentos.

RequestLogger — Logging privacy-safe. NUNCA registra: bodies (prompts/outputs), headers auth, User-Agent. Solo: método, path, status, duración.

Exception Handlers

Manejo centralizado de excepciones via register_exception_handlers(app). Mapea toda la jerarquia HFLError a respuestas HTTP con codigos apropiados (400 para validacion, 429 para rate limit, 500 para errores internos).

OpenAPI Documentation

Todos los endpoints incluyen tags, summary y responses en sus decoradores para documentacion OpenAPI auto-generada. Tags: OpenAI, Ollama, TTS, Health, Metrics.

Structured Logging

Todo el logging usa format strings %-style (logger.info('Model loaded: %s', name)) en lugar de f-strings, evitando evaluacion innecesaria cuando el nivel de log esta deshabilitado.

Health & Metrics Endpoints

/health/deep?probe=true — Ejecuta un test de inferencia minimo para verificar que el modelo funciona correctamente. Si falla, reporta estado "degraded".

/health/sli — Service Level Indicators con metricas de disponibilidad y latencia.

/metrics — Metricas en formato Prometheus.

/metrics/json — Metricas en formato JSON.

12. Módulo i18n — Internacionalización

Archivo: src/hfl/i18n/__init__.py

Sistema de internacionalización completo que permite al CLI mostrar todos sus mensajes en múltiples idiomas. Utiliza archivos JSON de traducción con claves anidadas y acceso mediante notación de puntos.

Funciones Principales

FunciónDescripción
t(key, **kwargs)Traduce una clave (ej: t("commands.pull.downloading")). Soporta interpolación con .format(**kwargs). Cache con lru_cache para rendimiento.
get_language()Retorna el idioma actual. Lee de HFL_LANG env var, default "en"
set_language(lang)Cambia el idioma en runtime y limpia la caché de traducciones
_load_translations(lang)Carga el archivo JSON del idioma desde locales/
_get_nested_value(data, key)Navega diccionarios anidados con notación de puntos

Archivos de Traducción

Cada idioma tiene un archivo JSON (~193 líneas) en src/hfl/i18n/locales/:

en.json (inglés) y es.json (español). Las claves siguen la estructura module.action.message, por ejemplo: commands.pull.downloading, commands.search.no_results, errors.model_not_found.

Uso: Configurar idioma con export HFL_LANG=es. Todos los comandos CLI utilizan t() para sus mensajes, permitiendo cambiar el idioma sin modificar código.

13. Jerarquía de Excepciones

Árbol de Excepciones Personalizadas
HFLError ModelNotFoundError ModelAlreadyExistsError DownloadError NetworkError ConversionError ToolNotFoundError LicenseError LicenseNotAcceptedError GatedModelError EngineError ModelNotLoadedError MissingDependencyError OutOfMemoryError AuthenticationError InvalidTokenError TokenRequiredError ConfigurationError InvalidConfigError

Todas heredan de HFLError(message, details) con __str__ que combina ambos. Cada excepción incluye datos contextuales específicos (model_name, repo_id, required_gb, etc.) para diagnóstico detallado.

14. Flujo Completo: hfl pull

Pipeline de Descarga y Registro de Modelo
1. Resolverresolver.py 2. Licencialicense_checker.py 3. Descargardownloader.py 4. Detectar fmtformats.py 5. Convertir?gguf_converter.py(solo si no es GGUF)safetensors→FP16→Qx 6. Crear Manifestmanifest.py 7. Registrarregistry.add() HfApi.model_info() check + accept hf_hub_download/ snapshot_download models.json

15. Flujo Completo: hfl run

Pipeline de Chat Interactivo
1. Registry.get()buscar por nombre/alias 2. select_engine()auto → formato + HW 3. engine.load()cargar en RAM/VRAM 4. Chat Loopinput → messages.append()→ chat_stream()→ print tokens 5. /exitengine.unload() loop hasta /exit

16. Flujo Completo: hfl serve

Pipeline del Servidor API
ClienteHTTP/SSE MiddlewareCORSAPIKeyDisclaimer (R9)Privacy Logger (R6) Routerroutes_openai.pyroutes_native.py/health, / _ensure_model_loadedRegistry → select_engine→ engine.load() (si necesario) Enginechat() / generate()chat_stream() ... ResponseJSON / SSE Auto-carga: si se pide modelo distinto, descarga el actual y carga el nuevo

18. Patrones de Diseño

Strategy Pattern (Engine)

La interfaz InferenceEngine (ABC) define el contrato. Tres implementaciones concretas (LlamaCpp, Transformers, vLLM) son intercambiables. El selector.py actúa como factory que elige la estrategia correcta según contexto.

Lazy Loading / Lazy Imports

Todas las dependencias pesadas (torch, transformers, vllm, llama-cpp-python) se importan solo cuando se necesitan. Los imports dentro de funciones evitan que una instalación mínima falle por dependencias opcionales ausentes.

Dependency Injection Container

core/container.py implementa un contenedor DI con singletons thread-safe (double-checked locking). Provee get_config(), get_registry(), get_state(), get_event_bus(), get_metrics(). Facilita testing con reset_container().

Dataclass como Value Objects

ChatMessage, GenerationConfig, GenerationResult, ModelManifest, ResolvedModel, ConversionRecord, LicenseInfo — todos son dataclasses inmutables o semi-inmutables que encapsulan datos.

Pipeline / Chain (CLI pull)

El comando pull implementa un pipeline secuencial de 7 pasos: resolver → verificar licencia → descargar → detectar formato → convertir (condicional) → crear manifest → registrar. Cada paso es un componente desacoplado.

Adapter Pattern (API dual)

Los mismos motores de inferencia se exponen a través de dos interfaces API diferentes (OpenAI y Ollama) mediante routers separados que adaptan los formatos de request/response al formato esperado por cada ecosistema.

Circuit Breaker + Retry

utils/circuit_breaker.py implementa circuit breaker para llamadas externas. utils/retry.py provee retry con exponential backoff configurable. Ambos mejoran la resiliencia ante fallos de red o servicios externos.

Event Bus (Pub/Sub)

events.py implementa un EventBus interno para comunicación desacoplada entre componentes. Permite suscribirse a eventos como model_loaded, inference_complete, download_progress sin crear dependencias directas.

Architecture Decision Records (ADRs)

Las decisiones arquitectónicas importantes están documentadas en docs/adr/ siguiendo el formato estándar ADR:

ADRTítuloEstado
0001Singleton Pattern para Config y RegistryAccepted
0002API Async con Engines Sync (sync_to_thread)Accepted
0003GGUF como Formato DefaultAccepted
0004Compatibilidad API OllamaAccepted
0005Clasificación de Licencias (5 niveles)Accepted
0006Estrategia de Rate LimitingAccepted

19. Dependencias y Extras

Mapa de Dependencias por Grupo
Core (siempre instalado) typer rich huggingface-hub fastapi uvicorn pydantic httpx sse-starlette pyyaml [llama] llama-cpp-python ≥0.3 [transformers] transformers ≥4.47 torch ≥2.5 accelerate ≥1.2 sentencepiece [vllm] vllm ≥0.6 [convert] gguf ≥0.10 [dev] pytest ≥8.0 pytest-asyncio ruff ≥0.8 pytest-cov [build] pyinstaller ≥6.0 | [all] = llama + transformers + vllm + convert Build system: hatchling | Target: Python ≥3.10 | Linting: ruff (E, F, W, I) | Line length: 100

20. Testing

Cobertura: 90%+ con 1900 tests — Suite exhaustiva con pytest + pytest-asyncio (asyncio_mode = "auto"). 80+ archivos de test con fixtures compartidas en conftest.py.

Categorías de Tests

Core & Config

test_config.pyHFLConfig, paths, env vars
test_container.pyDI container, Singleton pattern
test_exceptions.pyJerarquía de excepciones
test_events.pyEventBus, pub/sub
test_metrics.pyMétricas de rendimiento
test_validators.pyValidación de datos
test_security.pySeguridad y sanitización

API Server

test_api*.py (5)Endpoints, auth, contracts
test_routes_*.py (4)OpenAI, Native, TTS
test_state.pyServerState, async locks
test_streaming.pySSE streaming
test_model_loader.pyCarga dinámica de modelos
test_helpers.pyensure_llm/tts_loaded
test_middleware.pyPrivacy logger, disclaimer

Engine & Inference

test_engine*.py (2)Base, LlamaCpp
test_selector*.py (3)Auto-selección backend
test_transformers*.py (2)TransformersEngine
test_vllm_engine.pyvLLM con mocks
test_tts_*.py (2)Bark, Coqui TTS
test_async_wrapper.pySync→Async wrapper
test_model_pool.pyPool de modelos

Hub & Downloads

test_hub*.py (2)Integración HF Hub
test_downloader*.py (2)Descarga con resume
test_resolver*.py (2)Resolución de modelos
test_license_checker.pyClasificación licencias
test_auth.pyAutenticación HF

CLI & Utils

test_cli*.py (4)Comandos Typer
test_converter*.py (3)GGUF conversion
test_i18n*.py (4)Internacionalización
test_circuit_breaker.pyCircuit breaker
test_retry.pyRetry con backoff

Tests de Integración y Edge Cases

test_integration.pyFlujos end-to-end completos (pull→run→serve)
test_concurrency.pyConcurrencia, thread safety, race conditions
test_network_errors.pyTimeouts, disconnects, retry logic
test_edge_cases.pyInputs malformados, estados límite
test_server_lifecycle.pyStartup, shutdown, cleanup

Tests Adicionales (v0.1.0)

Signal handling CLICtrl+C durante streaming preserva respuesta parcial
Middleware orderVerifica orden correcto de ejecucion del middleware stack
Exception handlersMapeo HFLError → HTTP status codes
Health probeDeep health check con inferencia minima
Config env varsOverride de configuracion via variables de entorno
Model pool waitEspera no recursiva (bounded polling)
Stress testsConcurrent streaming, model pool stress
TimeoutDecorator @with_timeout y timeout configurable
FailoverMulti-engine retry con sticky routing
Per-model rate limitRate limiting diferenciado por modelo
Conversion cachingCache de conversiones GGUF

Fixtures principales (conftest.py): tmp_hfl_home (directorio temporal), mock_hf_api (mock HfApi), sample_manifest (modelo ejemplo), populated_registry (registro pre-populado), mock_engine (engine de inferencia mockeado), test_client (FastAPI TestClient).

# Ejecutar tests con cobertura
pytest --cov=hfl --cov-report=html --cov-fail-under=80

# Tests por categoría
pytest tests/test_api*.py -v          # Solo API
pytest tests/test_engine*.py -v       # Solo engines
pytest -k "not slow" -v               # Excluir tests lentos

21. Build y Distribución

Build System: Hatchling

Configurado en pyproject.toml. Packages source en src/hfl. Entry point: hfl = "hfl.cli.main:app". Instalación con pip install . o pip install .[all] para todas las dependencias opcionales.

PyInstaller (hfl.spec)

Spec para generar ejecutable standalone. Permite distribuir HFL como binario único sin requerir Python instalado. Se genera con pyinstaller hfl.spec y el resultado queda en dist/hfl.

Almacenamiento Local

~/.hfl/
├── models/               # Archivos de modelos descargados
│   └── org--model/       # Directorio por modelo (org--model format)
├── cache/                # Caché de HuggingFace Hub
├── tools/
│   └── llama.cpp/        # Herramientas compiladas para conversión
│       └── build/bin/    # Binarios: llama-quantize, etc.
├── models.json           # Registro de modelos (array de ModelManifest)
└── provenance.json       # Log inmutable de conversiones

22. CI/CD y GitHub

GitHub Actions Workflows

WorkflowTriggerDescripción
ci.ymlPush/PR a mainPipeline completo: lint (ruff) + tests (pytest matrix Python 3.10/3.11/3.12) + type-check
pages.ymlPush a mainDeploy automático de docs HTML a GitHub Pages
build-executables.ymlRelease/manualBuild ejecutables multiplataforma con PyInstaller
lint.ymlPush/PRLinting con ruff (E, F, W, I)
test.ymlPush/PRTests con pytest + coverage
security.ymlProgramado/manualAuditoría de seguridad de dependencias
license-check.ymlPush/PRVerificación de licencias de dependencias

Templates de GitHub

Issue Templates: bug_report.yml (formulario estructurado con info de sistema, pasos para reproducir, logs) y feature_request.yml (problema, solución propuesta, componente afectado).

PR Template: Checklist que incluye verificación de los 5 Compliance Modules (licencia, provenance, disclaimer, privacidad, gating) según requisitos de la HRUL.

Archivos de comunidad: CONTRIBUTING.md (guía de desarrollo, estilo de código, proceso de PR), CODE_OF_CONDUCT.md (Contributor Covenant v2.1), SECURITY.md (política de reporte de vulnerabilidades).

HFL v0.1.0 — Documentación de Arquitectura Exhaustiva

Actualizado el 7 de marzo de 2026 — Todos los diagramas son SVG interactivos

Licencia: HRUL v1.0 (source-available) — Copyright © 2026 Gabriel Galán Pelayo