# EdgeVision — Especificación técnica y estado actual del proyecto

**Proyecto:** Diseño, montaje e implementación de un clúster de Edge Computing para inferencia de inteligencia artificial local autónoma  
**Nombre de la solución:** EdgeVision  
**Línea funcional:** Visión por computadora, detección de objetos y análisis multimodal local  
**Versión funcional más reciente observada:** **2.0.5.1**  
**Fecha de corte del documento:** 16 de octubre de 2026  
**Entorno:** Laboratorio físico con Orange Pi 4 Pro, laptop Windows 11, máquina virtual Ubuntu y red Ethernet privada  
**Formato:** Especificación técnica y documento de transferencia de contexto para el equipo, GitHub y herramientas de desarrollo

> **Alcance y fiabilidad de esta especificación.** Documento reconstruido a partir de las conversaciones, capturas y salidas de comandos compartidas durante el desarrollo, junto con los archivos fuente de los paquetes EdgeVision 2.0–2.0.5.1 preparados para el laboratorio. No es una lectura directa en tiempo real de los sistemas Windows/Ubuntu/Orange Pi. Se diferencian resultados observados, confirmaciones del operador y verificaciones pendientes. No se inventan medidas ni resultados de pruebas.

## 0. Resumen ejecutivo

EdgeVision es un sistema académico de **inferencia de IA local sin API externa de generación**. Combina dos modalidades:

1. **Análisis multimodal:** cargar una fotografía desde un navegador o capturar un fotograma desde la webcam; hacer una pregunta; procesar la imagen con **Qwen3-VL-2B-Instruct** en `llama.cpp`; mostrar una explicación en español.
2. **Detección por webcam:** una **cámara USB físicamente conectada a Orange Pi** alimenta a **YOLO11-Nano** ejecutado sobre **ONNX Runtime CPU/ARM64**. El portal muestra video MJPEG anotado con objetos, clases y recuadros, además de poder capturar un fotograma original para el VLM.

La máquina virtual Ubuntu actúa como **coordinador**, alojando el portal, la API y el motor VLM. La Orange Pi actúa como **nodo Worker**, ofreciendo inferencia remota de `llama.cpp` por **RPC**, detección YOLO, métricas y supervisión pasiva RPC. Los nodos están conectados mediante switch Gigabit y cables CAT6 en la subred `192.168.100.0/24`.

EdgeVision admite dos rutas para el VLM:

- **`RPC + VM`:** descarga configurada de un subconjunto de capas/operaciones al dispositivo RPC remoto de Orange Pi; el resto del trabajo, incluido el proyector visual, permanece en Ubuntu.
- **`Solo VM`:** respaldo en frío por CPU local; puede requerir reiniciar `llama-server` y volver a ejecutar la petición.

**Estado reciente:** el portal mostró una sesión estable `RPC + VM` tras aplicar la corrección 2.0.5.1, y completó la descripción de la fotografía de un automóvil. Para **certificar** que esa solicitud usó cálculo remoto debe examinarse el registro `inferencias.jsonl` de la solicitud junto con las asignaciones `RPC0` de su **mismo `model_session_id`**; aún no se compartió el resultado final de esa comprobación.

### 0.1. Convención de estados

| Etiqueta | Interpretación |
|---|---|
| **VERIFICADO** | Hay captura, salida de comando o respuesta de servicio compartida que respalda directamente el hecho. |
| **REPORTADO** | El operador indicó que lo realizó, pero no se adjuntaron todos los registros de aceptación. |
| **IMPLEMENTADO** | La función aparece en el código/paquete, sin que eso por sí solo pruebe funcionamiento físico en todos los escenarios. |
| **PENDIENTE** | Falta una prueba, evidencia o cierre académico. |
| **LIMITACIÓN** | Restricción conocida de la arquitectura o del proyecto. |

---

# 1. Problema, objetivos y alcance

## 1.1. Problema empresarial

Un negocio que analiza fotografías, productos u objetos mediante plataformas externas de IA puede depender del acceso a Internet, sufrir costos por tokens/solicitudes y transferir datos a infraestructura ajena. El proyecto propone mantener la inferencia dentro de la infraestructura del laboratorio, usando equipos accesibles de bajo consumo y experimentando con procesadores ARM64 y x86-64.

**Precisión conceptual:** el sistema elimina la necesidad de pagar una **API externa por inferencia** en este escenario, pero **no elimina** los gastos de equipo, energía, almacenamiento, mantenimiento o el tiempo de procesamiento. La operación desconectada se aplica a la fase de inferencia con pesos ya descargados; instalar paquetes y modelos inicialmente puede requerir Internet.

## 1.2. Objetivo general

Construir y demostrar una plataforma de Edge Computing de inferencia de IA local, con procesamiento visual en Orange Pi, análisis multimodal en Ubuntu, posibilidad de trabajo distribuido mediante RPC, supervisión de nodos y recuperación controlada del VLM a CPU local.

## 1.3. Objetivos específicos

1. Instalar y administrar Debian ARM64 en Orange Pi y Ubuntu Server x86-64 en VirtualBox.
2. Integrar ambos sistemas en una red privada mediante switch Gigabit, cables CAT6, SSH e IP internas definidas.
3. Compilar y ejecutar `llama.cpp` con soporte RPC compatible en ambas arquitecturas.
4. Ejecutar un SLM de texto como prueba basal y contrastar velocidades CPU local frente a RPC.
5. Instalar Qwen3-VL cuantizado con su proyector visual y ofrecer análisis desde un portal web.
6. Implementar una webcam física USB y YOLO11-Nano por ONNX Runtime en Orange Pi.
7. Habilitar captura de fotogramas, monitoreo de CPU/RAM y registros de inferencia.
8. Incorporar una ruta de respaldo VLM en CPU de Ubuntu ante indisponibilidad RPC.
9. Demostrar reinicio, comportamiento sin Internet y funcionamiento según evidencia.
10. Preparar informe, repositorio, sitio de presentación y defensa académica.

## 1.4. Dentro y fuera del alcance

**Incluye:** plataforma local, dos modalidades de visión, API HTTP privada, middleware RPC, monitoreo, scripts de instalación, controles de cambio de modo, logs y evidencia académica.

**No incluye (estado actual):** API pública con autenticación robusta, SLA de producción, cifrado nativo de RPC, GPU dedicada, clúster Kubernetes, redundancia física de switch/enlaces, escalado horizontal automático de varios Workers, balanceo multiworker robusto o conmutación sin interrupción de una petición que estaba en curso. No debe presentarse como alta disponibilidad de nivel empresarial.

---

# 2. Inventario físico y recursos

| Recurso | Especificaciones conocidas | Papel |
|---|---|---|
| **Orange Pi 4 Pro** | Placa ARM64, **8 núcleos**, **4 GB RAM**; familia de placa Orange Pi 4 Pro **A733** identificada en material inicial. | Worker RPC, YOLO, cámara, métricas, observador. |
| **Laptop principal** | Windows 11; **16 GB RAM**, **6 núcleos** declarados; NIC **Realtek Gaming 2.5GbE Family Controller**; adaptador Wi-Fi MediaTek. | Anfitrión VirtualBox, navegador y administración. |
| **Máquina virtual Ubuntu** | Ubuntu Server 24.04 LTS **AMD64/x86-64**, VirtualBox, **3 vCPU**, aprox. **8 GiB de RAM observados en documentación del laboratorio**; perfil inicial proponía 7168 MB, por lo que se debe confirmar la asignación final directamente en VirtualBox. | Master, FastAPI, llama-server, archivos GGUF. |
| **Switch** | Switch no administrado **Gigabit Ethernet, 5 puertos**. | Interconexión LAN. |
| **Cableado** | Al menos dos cables Ethernet CAT6. | Laptop ↔ switch ↔ Orange Pi. |
| **Webcam USB** | Compatible con Video4Linux; detectada como **`/dev/video0`** en pruebas. | Fuente de imágenes para detección y capturas. |
| **Arranque/almacenamiento** | Soporte del sistema en Orange Pi y disco virtual de Ubuntu; perfil inicial propuso VDI dinámico de 60 GB. | Sistemas, proyectos y pesos. |
| **Periféricos de instalación** | Monitor/HDMI, teclado y alimentación compatible para Orange Pi. | Instalación y recuperación presencial. |

**No asumir** el modelo exacto de CPU/GPU, memoria asignada o tamaño de disco sin ejecutar `lscpu`, `free -h`, `lsblk` o revisar VirtualBox; esta ficha distingue las observaciones históricas del inventario certificado.

## 2.1. Restricciones de rendimiento

- Ubuntu se configuró con **3 hilos de CPU** para llama.cpp.
- Orange Pi tiene **4 GB RAM** y comparte recursos entre RPC, YOLO y servicios ligeros.
- No se cuenta con GPU dedicada externa en el diseño.
- La webcam/YOLO se configuró para operar aproximadamente a **1 FPS objetivo**, con **2 hilos ONNX**; el rendimiento medido fue aproximadamente **1.26 FPS** en una prueba.
- El VLM utiliza **una sola instancia residente** de `llama-server` (en modo RPC o local, no ambos simultáneamente), para contener consumo de RAM.
- La inferencia multimodal sobre CPU puede tardar varios minutos por fotografía.

---

# 3. Arquitectura del sistema

## 3.1. Diagrama físico y lógico

```mermaid
flowchart TB
    U[Usuario / Windows 11\nNavegador] -->|HTTP por NAT 127.0.0.1:18000| V
    subgraph LAPTOP[Windows 11 + VirtualBox]
      subgraph V[Ubuntu Server x86-64 / Master]
        PORTAL[FastAPI + HTML/CSS/JS\n0.0.0.0:8000]
        ENGINE[ModelEngine / watchdog / auditoría]
        LLAMA[llama-server + Qwen3-VL Q4\nmmproj Q8 - 127.0.0.1:8081]
        PORTAL --> ENGINE --> LLAMA
      end
    end
    subgraph LAN[LAN privada - Switch Gigabit / CAT6]
      SW[(Switch Ethernet)]
    end
    LLAMA <-->|ggml RPC TCP :50052| SW
    PORTAL <-->|Cámara MJPEG y captura / HTTP :9200| SW
    ENGINE <-->|Observación pasiva RPC / HTTP :9101| SW
    PORTAL <-->|Métricas CPU/RAM / HTTP :9100| SW
    subgraph PI[Orange Pi 4 Pro - Debian ARM64 / Worker]
      RPC[ggml-rpc-server :50052]
      CAM[Webcam USB /dev/video0\nOpenCV + YOLO11n ONNX CPU :9200]
      MET[Monitor CPU/RAM :9100]
      OBS[Observador RPC pasivo :9101]
    end
    SW --- RPC
    SW --- CAM
    SW --- MET
    SW --- OBS
```

**Interpretación:** el switch transporta comunicación LAN; **NO** significa que todas las flechas pasen por un único proceso. Los servicios RPC, webcam, métricas y observación son independientes dentro de Orange Pi.

## 3.2. Separación de responsabilidades

| Ubicación | Responsabilidades |
|---|---|
| **Windows** | VirtualBox, PowerShell/SSH, navegador EdgeVision, instaladores `.bat`/`.ps1`, edición y exportación de código. |
| **Ubuntu Master** | API FastAPI, interfaz web, validación de archivos, preparación de imágenes, control de `llama-server`, coordinación RPC, fallback local, auditoría e informes de estado. |
| **Orange Pi Worker** | Exponer su backend de cómputo mediante `ggml-rpc-server`, ejecutar YOLO en ARM64, leer webcam física, transmitir MJPEG, devolver JPEG original, publicar métricas y estado del listener RPC. |

**Concepto de distribución:** el código de aplicación y los modelos no se convierten automáticamente en una única CPU. El backend RPC de `llama.cpp` puede distribuir tensores y ciertas operaciones a un dispositivo remoto, con costos de transferencia de datos, coordinación y posibles restricciones de compatibilidad.

---

# 4. Redes, direccionamiento y administración

## 4.1. Diseño de subredes

| Equipo | Interfaz | IP/red de referencia | Uso |
|---|---|---|---|
| Ubuntu | `enp0s3` | **`192.168.100.10/24`** | Ethernet privada en puente sobre Realtek. |
| Orange Pi | `end0` | **`192.168.100.20/24`** | Enlace privado al clúster. |
| Orange Pi | `end0` | **`192.168.137.20/24`** (secundaria) | Red temporal de Internet compartido (ICS), si Windows la proporciona. |
| Windows Ethernet | Realtek | Frecuentemente `192.168.137.1/24` con ICS | Internet compartido opcional; puede variar. |
| Ubuntu | `enp0s8` | DHCP NAT VirtualBox, p. ej. `10.0.3.15/24` | Administración/Internet durante instalación. |
| Windows → Ubuntu | loopback `127.0.0.1` | `2222` SSH, `18000` HTTP | Reenvío NAT estable hacia puertos `22` y `8000` de la VM. |

- Red de cómputo dedicada: `192.168.100.0/24`.
- La red privada no necesita gateway por defecto para Ubuntu ↔ Orange Pi.
- **Ubuntu:** configuración persistente mediante Netplan.
- **Orange Pi:** perfil de NetworkManager `edgevision-end0`, con autoconexión.
- **REPORTADO:** el operador indicó que realizó la prueba de reinicio y funcionamiento sin Internet. Conviene conservar capturas posteriores al reinicio, `ip -4 -br addr`, `systemctl is-active` y ejecución offline.
- La antigua dirección DHCP `192.168.137.128` de Ubuntu **no debe codificarse como acceso fijo**. La URL preferida desde la laptop es `http://127.0.0.1:18000/`.

## 4.2. Tabla completa de puertos

| Puerto | Equipo | Servicio | Tipo de acceso | Ruta de ejemplo |
|---|---|---|---|---|
| **22/tcp** | Ubuntu / Orange Pi | OpenSSH | Administración | `ssh` |
| **50052/tcp** | Orange Pi `.20` | `ggml-rpc-server` | RPC del modelo; **no sondear activamente cuando está en uso** | protocolo ggml RPC |
| **9200/tcp** | Orange Pi `.20` | YOLO/cámara | HTTP privado | `/status`, `/stream.mjpg`, `/snapshot.jpg` |
| **9100/tcp** | Orange Pi `.20` | Monitor CPU/RAM 2.0.4 | HTTP privado | `/metrics` |
| **9101/tcp** | Orange Pi `.20` | Observador pasivo RPC 2.0.5.1 | HTTP privado | `/rpc-health` |
| **8081/tcp** | Ubuntu `127.0.0.1` | `llama-server` | Loopback únicamente | `/health`, `/v1/chat/completions` |
| **8000/tcp** | Ubuntu | FastAPI EdgeVision | LAN/controlada | `/`, `/api/status`, `/api/analyze` |
| **2222/tcp** | Windows `127.0.0.1` | VirtualBox NAT forwarding | SSH local al anfitrión | Ubuntu `:22` |
| **18000/tcp** | Windows `127.0.0.1` | VirtualBox NAT forwarding | Web local al anfitrión | Ubuntu `:8000` |

**Advertencia:** las interfaces web y servicios internos no están diseñados con autenticación pública. No abrir el puerto 50052, 9200, 9100, 9101 o 8000 directamente a Internet.

## 4.3. Conexión SSH desde Windows

```powershell
# En Windows PowerShell; requiere regla NAT de VirtualBox:
ssh -p 2222 milo@127.0.0.1

# Saltar por Ubuntu hacia Orange Pi desde Windows:
ssh -J milo@127.0.0.1:2222 orangepi@192.168.100.20
```

Desde Ubuntu:

```bash
ssh orangepi@192.168.100.20
```

**Precaución:** el reenvío NAT de VirtualBox depende de la configuración actual de la VM, por lo que hay que comprobar su persistencia y que no existan reglas duplicadas.

---

# 5. Sistemas operativos, software y librerías

## 5.1. Sistemas y herramientas base

| Componente | Sistema/tecnología | Nota |
|---|---|---|
| Anfitrión | Windows 11 | Navegador, PowerShell, SSH, instaladores. |
| Hipervisor | Oracle VirtualBox 7.x | Puente a Realtek y segundo adaptador NAT. |
| Master | Ubuntu Server 24.04 LTS AMD64 | Aplicación API y modelo multimodal. |
| Worker | Debian 12 Bookworm ARM64 | Modelo YOLO, RPC, servicios. |
| Runtime multimodal | `llama.cpp` / GGML | Binarios `llama-server`, `llama-cli`, `ggml-rpc-server`. |
| Compilación | CMake, Ninja, GCC/G++, Git, OpenMP | RPC habilitado en compilación. |
| Backend web | Python 3, FastAPI, Uvicorn, HTTPX, Pillow | API del portal y comunicación con modelos. |
| Web | HTML5, CSS3, JavaScript | Interfaz estática servida por FastAPI. |
| Cámara | Video4Linux2 (`/dev/video0`), OpenCV | Captura física desde Orange Pi. |
| Inferencia YOLO | ONNX Runtime CPU, NumPy | No necesita PyTorch instalado en Orange Pi. |
| Supervisión | `psutil`, `systemd`, `/proc/net/tcp` | CPU/RAM, procesos y listener RPC. |
| Administración | SSH, SCP, `journalctl`, `systemctl`, `curl`, `tmux` (histórico) | Despliegue y diagnóstico. |

## 5.2. Dependencias del backend FastAPI

Declaración de requisitos del paquete:

```text
fastapi>=0.115,<1
uvicorn>=0.30,<1
httpx>=0.27,<1
pillow>=10,<13
python-multipart>=0.0.9,<1
python-dotenv>=1.0,<2
psutil>=6,<8
```

## 5.3. Dependencias del Worker de cámara

```text
numpy>=1.26,<2
opencv-python-headless>=4.9,<4.12
onnxruntime>=1.20,<1.32
```

En una instalación real se observaron, entre otras, `numpy 1.26.4`, `opencv-python-headless 4.11.0.86` y `onnxruntime 1.31.0` sobre ARM64. Estos son valores históricos de esa instalación, no un inventario completo obtenido hoy mediante `pip freeze`.

---

# 6. Modelos de inteligencia artificial

## 6.1. Comparativa de modelos

| Modelo/archivo | Ubicación | Función | Estado |
|---|---|---|---|
| **Qwen2.5-0.5B-Instruct Q4_K_M GGUF** | Ubuntu `~/models/` | Prueba inicial de lenguaje y RPC, medición basal. | **VERIFICADO** texto local + RPC. |
| **Qwen3VL-2B-Instruct-Q4_K_M.gguf** | Ubuntu `~/edge-vision-models/` | Modelo de lenguaje multimodal para interpretar imágenes. | **VERIFICADO** respuestas, incluida fotografía del gato y automóvil. |
| **mmproj-Qwen3VL-2B-Instruct-Q8_0.gguf** | Ubuntu `~/edge-vision-models/` | Proyector visual de Qwen3-VL. | **IMPLEMENTADO** y utilizado en respuestas multimodales. |
| **yolo11n.onnx** | Orange Pi `~/edgevision-camera/models/` | Detectar objetos en webcam. | **VERIFICADO** `/status`, imágenes y flujo de cámara. |

Qwen3-VL tiene aproximadamente **2.000 millones de parámetros**. El formato GGUF facilita su ejecución mediante GGML/llama.cpp. **Q4** reduce memoria al cuantizar pesos; **Q8** identifica el formato del componente proyector utilizado.

En el instalador inicial se describía un tamaño aproximado de **1.11 GB** del VLM Q4 y **445 MB** del proyector Q8. Puede variar según revisión exacta. La exportación ONNX verificada ocupaba del orden de **10 MB**.

## 6.2. Qué hace y qué no hace cada modelo

**YOLO11-Nano:** recibe un fotograma; produce candidatos de clase, confianza y coordenadas; aplica decodificación y supresión de cajas solapadas; dibuja bounding boxes. No redacta por sí mismo una descripción lingüística larga.

**Qwen3-VL:** recibe la imagen preprocesada y un mensaje textual, y genera una respuesta en lenguaje natural. No reemplaza los bounding boxes de YOLO ni promete identificación infalible de objetos/textos. Puede alucinar o repetirse, especialmente con imágenes oscuras o prompts extensos.

**RPC:** no es un modelo adicional; es un mecanismo de comunicación que permite usar la CPU remota de Orange Pi para determinadas operaciones del VLM cuando el modo `rpc` está realmente activo.

---

# 7. Lógica de Qwen3-VL y parámetros de inferencia

## 7.1. Configuración efectiva prevista en 2.0.5.1

En el código `backend/engine.py` se construye `llama-server` con opciones equivalentes a:

```bash
/home/milo/llama.cpp/build/bin/llama-server \
  -m /home/milo/edge-vision-models/Qwen3VL-2B-Instruct-Q4_K_M.gguf \
  --mmproj /home/milo/edge-vision-models/mmproj-Qwen3VL-2B-Instruct-Q8_0.gguf \
  --no-mmproj-offload \
  --host 127.0.0.1 --port 8081 \
  --alias edgevision-vlm \
  -ngl 8 -t 3 -c 4096 -b 512 -ub 512 \
  --image-max-tokens 512 -np 1 -lv 5 \
  --rpc 192.168.100.20:50052
```

**Este bloque es representativo del modo RPC, no un comando para ejecutar en paralelo con el servidor que ya administra el portal.** Si se inicia manualmente una segunda instancia podrían aparecer conflictos de puerto/memoria.

En **modo Solo VM**, el motor omite `--rpc` y utiliza `-ngl 0`.

| Parámetro | Valor | Función |
|---|---|---|
| `VM_THREADS` | `3` | Hilos de CPU del proceso llama-server. |
| `RPC_LAYERS` | `8` | Cantidad objetivo de capas descargadas a dispositivo RPC (`-ngl`) si es compatible. |
| `CONTEXT_TOKENS` | `4096` | Ventana de contexto (`-c`). |
| `IMAGE_MAX_TOKENS` | `512` | Límite interno de tokens visuales (`--image-max-tokens`). |
| `-b / -ub` | `512 / 512` | Batch lógico / microbatch. |
| `-np` | `1` | Un slot de procesamiento simultáneo. |
| `--no-mmproj-offload` | Activado | Proyector visual en CPU de Ubuntu. |
| `GGML_RPC_NO_RDMA` | `1` | Transporte RPC TCP sin RDMA. |
| `GGML_RPC_DEBUG` | `1` si verbose | Registro detallado de operaciones RPC. |
| `EDGE_VERBOSE` | `true` | Log `-lv 5` en llama-server. |
| `EDGE_BOOT_TIMEOUT` | `210` en `.env` inicial; default del código `180` | Plazo para esperar a que el modelo esté listo. |
| `EDGE_UPSTREAM_TIMEOUT` | `480` segundos | Espera del backend HTTP por respuesta de llama-server. |

### 7.1.1. Variables en `.env` (ejemplo sin credenciales)

```dotenv
EDGE_AUTO_ENGINE=true
EDGE_RPC_HOST=192.168.100.20
EDGE_RPC_PORT=50052
EDGE_WORKER_METRICS_URL=http://192.168.100.20:9100/metrics
EDGE_RPC_OBSERVER_URL=http://192.168.100.20:9101/rpc-health
EDGE_CAMERA_URL=http://192.168.100.20:9200
EDGE_UPSTREAM_TIMEOUT=480
EDGE_BOOT_TIMEOUT=210
VM_THREADS=3
RPC_LAYERS=8
CONTEXT_TOKENS=4096
IMAGE_MAX_TOKENS=512
WEB_BIND=0.0.0.0
WEB_PORT=8000
EDGE_VERBOSE=true
```

No subir al repositorio un `.env` real con secretos u otros datos privados. Los valores son configuración de ejemplo, no lectura actual de la VM.

## 7.2. Lógica de recepción de fotografías

1. Navegador selecciona `JPG`, `PNG` o `WebP`, o usa una captura JPEG de Orange Pi.
2. `POST /api/analyze` recibe `multipart/form-data` con `image` y `question`.
3. Se validan pregunta de **1–1000 caracteres**, imagen de máximo **5 MiB** y límite de **6 megapíxeles**.
4. Pillow aplica corrección EXIF, conversión a RGB, reducción con miniatura a máximo **640 × 640** y compresión JPEG calidad **78**.
5. Se calcula prefijo SHA-256 de la imagen original (16 caracteres hexadecimales) para correlación de auditoría; la imagen se serializa temporalmente como `data:image/jpeg;base64,...`.
6. `ModelEngine.ensure_ready` comprueba que `llama-server` esté funcionando. Si no puede iniciarlo, puede intentar una recuperación local.
7. FastAPI envía el contenido a la API de `llama-server` `POST /v1/chat/completions` con un mensaje multimodal (texto + `image_url` de tipo data URI).
8. Los parámetros de generación usados en código son `max_tokens: 180`, `temperature: 0.1`, `stream: false`.
9. El resultado se extrae de `choices[0].message.content`; se presenta en el navegador y se registra el modo/tiempo/sesión.
10. La solicitud se **serializa** para no lanzar múltiples análisis concurrentes sobre el mismo motor; la cámara YOLO se puede pausar temporalmente y reanudar al concluir.

**Tratamiento de datos:** el código del portal no almacena por defecto copias permanentes de cada fotografía subida; sí genera registros (metadatos, sesión, tiempo, hash parcial y errores) que requieren revisión antes de publicarlos.

## 7.3. Diagrama de flujo de análisis multimodal

```mermaid
sequenceDiagram
    participant User as Usuario/navegador
    participant Web as Portal FastAPI :8000
    participant Eng as ModelEngine
    participant VLM as llama-server :8081
    participant RPC as Orange Pi ggml RPC :50052
    User->>Web: Imagen + prompt
    Web->>Web: Validar, reducir, JPEG Base64
    Web->>Eng: Asegurar proceso listo
    Eng->>VLM: Control de estado /health
    Web->>VLM: POST /v1/chat/completions
    opt Si modo rpc y hay capas remotas
        VLM->>RPC: Operaciones GGML/Tensores
        RPC-->>VLM: Resultados del cálculo
    end
    VLM-->>Web: Texto + estadísticas internas
    Web->>Web: Registro con request_id, mode, session_id
    Web-->>User: Respuesta y tiempo
```

---

# 8. RPC distribuido: diseño, supervisión y evidencia

## 8.1. Implementación RPC

El motor `llama.cpp` se compiló con backend RPC en Ubuntu x86-64 y Orange Pi ARM64. La revisión Git utilizada en la prueba de texto inicial fue:

```text
df18bee11e96557b07aa7b12db0976f3c7ac9165
```

**Validar** la revisión actualmente desplegada antes de afirmar que sigue siendo exactamente la misma en ambos equipos:

```bash
cd ~/llama.cpp && git rev-parse HEAD
```

En Orange Pi, la unidad `edgevision-rpc.service` (2.0.4) ejecuta:

```text
/home/orangepi/llama.cpp/build/bin/ggml-rpc-server
  --host 192.168.100.20 --port 50052 --threads 4
```

El RPC publicado por GGML es experimental y no dispone de controles para exponerlo sin protección en Internet.

## 8.2. Por qué el monitoreo anterior podía provocar falsa desconexión

En revisiones anteriores, el portal y el watchdog comprobaban disponibilidad abriendo conexiones TCP adicionales hacia `50052`. El servidor RPC de esa revisión puede mantener una conexión persistente de trabajo y tener capacidad limitada para atender sondeos simultáneos. Las conexiones de salud adicionales podían agotar el tiempo de espera y desencadenar falsos cambios `RPC + VM → Solo VM`.

Evidencia histórica: capturas donde el portal cambiaba entre `RPC + VM`, `starting local` y `Solo VM`, con aumento del contador de recuperaciones, mientras el servicio remoto reaparecía como disponible.

## 8.3. Corrección 2.0.5.1: observador pasivo independiente

- Conserva en `9100` el monitor previo de uso de CPU/RAM.
- Añade `edgevision-rpc-observer.service` en `9101`.
- El observador consulta **`/proc/net/tcp` localmente en Orange Pi** y devuelve:

```json
{
  "agent_version": "2.0.5.1",
  "rpc_observation": {
    "schema": "proc-net-tcp-v1",
    "port": 50052,
    "listening": true,
    "established_connections": 1,
    "source": "kernel-proc-net-tcp"
  }
}
```

La respuesta es **ejemplo de formato**. `listening: true` es evidencia de que el puerto está escuchando en el kernel, **no prueba de ejecución de capas remotas**. `listening: null` puede indicar que no se logró consultar el estado; no equivale automáticamente a `false`.

- FastAPI obtiene el estado por `GET http://192.168.100.20:9101/rpc-health` con caché y limitación de solicitudes concurrentes.
- El watchdog funciona aproximadamente cada **5 segundos** y exige **3 observaciones negativas** y al menos **10 segundos** de persistencia antes de recuperarse al modo local por ausencia de listener.
- Un error de lectura del observador (`ConnectTimeout`, etc.) se etiqueta como **sin confirmar**, no como caída segura de RPC.
- Un candado de actividad evita que el watchdog destruya a mitad de ejecución un modelo con una solicitud activa; un fallo real de transporte durante la solicitud puede activar respaldo.
- El retorno de `Solo VM` a `RPC + VM` es **manual** mediante el botón, para no interrumpir análisis activos.

En capturas de 2.0.5.1 ya se observó `RPC + VM` estable y, durante una petición exigente, el mensaje temporal **«Observador 9101 no disponible (ConnectTimeout); RPC sin confirmar»** sin caída inmediata a modo local. Se observó después una respuesta multimodal de la imagen del automóvil. Falta correlacionar su sesión para certificar cálculo remoto de esa respuesta concreta.

## 8.4. Diferencia entre conectividad RPC y cómputo RPC

**No equivalentes:**

1. `50052` escuchando → servidor/puerto disponibles.
2. `9101/rpc-health` → estado pasivo del listener.
3. Portal `RPC + VM` → el motor seleccionó y cargó la ruta distribuida.
4. Log con `load_tensors: layer N assigned to device RPC0` y `RPC0 ... compute buffer size` → asignación y reservas remotas.
5. Solicitud finalizada registrada como **`rpc-primary`** con el **mismo `model_session_id`** → correlación final de una inferencia sin fallback.

**Criterio de aceptación:** presentar conjuntamente **(4) y (5)** además del estado visual. Uso de CPU bajo o alto, por sí solo, no certifica la distribución.

## 8.5. Herramienta de certificación incluida en kit de exportación

Desde Windows se preparó:

```text
Validar-RPC-EdgeVision.bat
```

Genera `resultado_rpc.txt` leyendo únicamente los registros, sin sondear `50052`. Su lógica consulta la última línea válida de `inferencias.jsonl`, verifica que `mode == 'rpc-primary'`, recupera `model_session_id`, busca en el log el bloque **`start mode=rpc session_id=<id>`** y comprueba capas + buffers RPC0 y que no haya recuperación en esa petición.

**Estado de este control a la fecha de corte:** **PENDIENTE** recibir el informe de esa herramienta, ya que las capturas por sí solas no demuestran todos los puntos.

---

# 9. Conmutación y tolerancia a fallos

## 9.1. Estados del motor

| Estado interno | Interpretación visible |
|---|---|
| `stopped` | Motor apagado. |
| `starting-rpc` | Cargando instancia distribuida. |
| `rpc` | Instancia RPC iniciada y lista. |
| `starting-local` | Cargando respaldo CPU de Ubuntu. |
| `local` | Instancia local operativa (`Solo VM`). |
| `error` | La carga falló; revisar registros. |

## 9.2. Recuperación por CPU local

- Control de `llama-server`: un proceso a la vez, monitoreado desde `ModelEngine`.
- Si se confirma fallo relevante del Worker RPC o del proceso y no hay una petición activa, el motor puede detener su instancia y recargar el mismo VLM en modo **`-ngl 0` sin `--rpc`**.
- Si una solicitud en RPC falla, el controlador puede realizar un **reintento único** después del cambio a CPU local, sujeto a tiempo de espera y disponibilidad de RAM.
- El contador de recuperaciones registra eventos de cambio; **no prueba por sí solo** que haya una respuesta completa de respaldo.
- El sistema conserva independencia relativa entre webcam YOLO y RPC: caer RPC no implica necesariamente que deje de funcionar la cámara.

**LIMITACIÓN:** el respaldo es **en frío**, con recarga de pesos y posible reinicio de petición. No es HA sin tiempo de inactividad ni continuidad de estado/token de una inferencia truncada. Un solo switch implica un punto único de fallo físico.

## 9.3. Prueba controlada sugerida (no ejecutar con peticiones activas)

1. Obtener una inferencia RPC exitosa y certificada.
2. Con el VLM ocioso, detener **solo** `edgevision-rpc.service` en Orange Pi.
3. Verificar la transición a respaldo local y esperar su `/health`.
4. Ejecutar una nueva imagen y confirmar `mode: vm-fallback` con respuesta completa.
5. Restaurar el servicio RPC y recuperar la ruta desde el botón **Reactivar RPC**.
6. Guardar capturas, fechas, tiempos y entradas `inferencias.jsonl`/`supervision-rpc.jsonl`.

No detengas el sistema de cámara ni toda la Orange Pi para esta prueba si el objetivo es aislar el fallo del servicio de cómputo.

---

# 10. YOLO11-Nano: cámara, algoritmo y rendimiento

## 10.1. Pipeline técnico

```mermaid
flowchart LR
    A[Webcam USB /dev/video0] --> B[OpenCV / V4L2]
    B --> C[Redimensionar con letterbox]
    C --> D[YOLO11n ONNX / ONNX Runtime ARM64]
    D --> E[Confianzas + clases + cajas]
    E --> F[NMS por clase]
    F --> G[Dibujar recuadros y etiquetas]
    G --> H[MJPEG :9200/stream.mjpg]
    B --> I[JPEG original :9200/snapshot.jpg]
    I --> J[Qwen3-VL por FastAPI]
```

La exportación instalada de `yolo11n.onnx` espera entrada estática **`[1, 3, 480, 640]`** (alto × ancho, rectangular) y produce en esa revisión una salida compatible con **`[1, 84, 6300]`**. La versión 2.0.2 corrigió el servicio que solo aceptaba entradas cuadradas.

Procesamiento en el Worker:

1. Captura real de la webcam (resolución típica 640 × 480).
2. Preparación del tensor para altura/anchura reales del ONNX, normalización y letterbox.
3. Inferencia por ONNX Runtime CPU.
4. Decodificación de detecciones, filtro por confianza y supresión de duplicados mediante NMS.
5. Dibujo de recuadros, etiqueta y confianza sobre copia visualizada.
6. Streaming MJPEG anotado y captura JPEG **original**, sin recuadros, para el VLM.

## 10.2. Parámetros principales de cámara

| Parámetro | Valor inicial |
|---|---|
| `CAMERA_DEVICE` | Detección automática, normalmente `/dev/video0` |
| `CAMERA_BIND` | `192.168.100.20` |
| `CAMERA_PORT` | `9200` |
| `CAMERA_TARGET_FPS` | `1` FPS objetivo (no garantizado) |
| `CAMERA_ONNX_THREADS` | `2` |
| `CAMERA_CONFIDENCE` | `0.40` |
| ONNX input | `1 × 3 × 480 × 640` en la exportación corregida |
| Modelo | YOLO11-Nano ONNX, clases de detección general (COCO en exportación de referencia) |

## 10.3. Endpoints de cámara

| Método/ruta Orange Pi | Resultado |
|---|---|
| `GET /status` | `online`, modelo, webcam, FPS, ms de inferencia, detecciones, errores. |
| `GET /stream.mjpg` | Flujo MJPEG anotado con recuadros y clases. |
| `GET /snapshot.jpg` | JPEG reciente original, **sin** recuadros. |
| `POST /pause` | Pausa temporal de detección para liberar CPU. |
| `POST /resume` | Reactiva procesamiento. |

El portal actúa como proxy para presentar cámara y captura desde el mismo origen HTTP. Esto evita que el navegador requiera acceso directo a la IP privada del Worker.

## 10.4. Mediciones reales compartidas

Una respuesta `/status` de Orange Pi mostró:

```json
{
  "online": true,
  "model": "YOLO11n ONNX CPU",
  "camera_device": "/dev/video0",
  "frames_total": 27,
  "fps": 1.26,
  "paused": false,
  "inference_ms": 337.0,
  "detections": [],
  "last_error": null
}
```

Estos valores son **de aquella medición**, no cifras fijas de rendimiento. El retraso perceptible de la cámara se explica por la baja tasa de detección, el tiempo de cómputo, la compresión y la transmisión MJPEG.

**Dependencias y licencias:** el modelo se obtuvo de una exportación YOLO11-ONNX. Antes de redistribuir software/modelos en un contexto comercial, revisar las licencias de la exportación y la licencia aplicable a Ultralytics (incluida AGPL-3.0 donde corresponda). No asumir que todo es de dominio público.

---

# 11. Portal web y API

## 11.1. Características funcionales visibles

- Tema oscuro, estilo de panel administrativo.
- Pestaña **«Imagen · Qwen3-VL»** con selección/arrastre de JPG, PNG o WebP, vista previa, instrucción y respuesta.
- Pestaña **«Cámara en vivo · YOLO-Nano»** con streaming MJPEG, detecciones, métricas FPS y captura.
- Acción **«Capturar y analizar con Qwen3-VL»** sobre el fotograma original.
- Panel de disponibilidad de Orange Pi, Qwen3-VL y cámara.
- Estado de ruta `RPC + VM`/`Solo VM`, contador de recuperaciones y controles de cambio manual.
- Estadísticas de CPU y RAM de ambos equipos (cuando los monitores responden).
- Mensajes de error y recuperación sin necesidad de volver a capturar la foto.
- Metadatos de tiempo y modo utilizados como evidencia.

## 11.2. API FastAPI del Master

| Método/ruta | Propósito |
|---|---|
| `GET /` | Servir el HTML principal (`backend/static/index.html`). |
| `GET /api/status` | Estado agregado de VM, Worker, listener RPC, motor y cámara. |
| `POST /api/analyze` | Recibir imagen/prompt y ejecutar VLM con auditoría y fallback. |
| `POST /api/use-rpc` | Solicitar cambio manual al modo distribuido. |
| `POST /api/use-local` | Solicitar CPU local. |
| `GET /api/camera/status` | Estado remoto de cámara. |
| `GET /api/camera/snapshot` | Relay de la imagen original de la webcam. |
| `GET /api/camera/stream` | Relay MJPEG del Worker. |
| `POST /api/camera/pause` | Pausa temporal YOLO. |
| `POST /api/camera/resume` | Reanuda YOLO. |
| `GET /api/docs` | Documentación técnica OpenAPI de FastAPI, si no está deshabilitada. |

## 11.3. Ejemplo de auditoría JSONL

El backend `main.py` versión 2.0.5.1 escribe registros con esta estructura ilustrativa:

```json
{
  "utc": "2026-10-16T00:00:00+00:00",
  "request_id": "ejemplo-id",
  "starting_mode": "rpc",
  "starting_session_id": "sesion-ejemplo",
  "model_session_id": "sesion-ejemplo",
  "image_sha256_prefix": "hash-corto-ejemplo",
  "mode": "rpc-primary",
  "latency_seconds": 230.0,
  "recovered_this_request": false,
  "startup_recovered": false,
  "first_error": null
}
```

**Esta entrada es un ejemplo de esquema, NO una evidencia real.** La respuesta real de HTTP también incluye `distributed_verified: false` por diseño: esto indica que la aplicación no certifica de forma automática la ejecución remota; se requieren registros correlacionados con la sesión.

---

# 12. Directorios y código fuente

## 12.1. Ubuntu Master

```text
/home/milo/
├── llama.cpp/                            # Dependencia externa compilada
│   └── build/bin/
│       ├── llama-server
│       ├── llama-cli
│       └── ggml-rpc-server             # Binario disponible si se compiló
├── edge-vision-models/
│   ├── Qwen3VL-2B-Instruct-Q4_K_M.gguf
│   └── mmproj-Qwen3VL-2B-Instruct-Q8_0.gguf
├── models/
│   └── qwen2.5-0.5b-instruct-q4_k_m.gguf
└── edge-vision-lab/
    ├── backend/
    │   ├── engine.py                   # Modos RPC/local, watchdog, failover
    │   ├── main.py                     # FastAPI, imágenes, proxys, auditoría
    │   ├── static/index.html           # HTML/CSS/JavaScript de la interfaz
    │   ├── requirements.txt
    │   └── .env                        # Configuración local: no subir sin revisar
    ├── camera_worker/                  # Fuentes usadas para despliegue de cámara
    ├── scripts/
    │   ├── start.sh
    │   ├── stop.sh
    │   ├── status.sh
    │   ├── run_web.sh
    │   ├── install_vm.sh
    │   ├── install_camera_worker.sh
    │   ├── download_model.sh
    │   ├── benchmark.py
    │   └── ...
    ├── tests/
    ├── docs/
    └── evidencias/
        ├── modelo-vlm.log              # Logs de llama-server, sesiones RPC
        ├── portal.log                   # Accesos/errores de FastAPI
        ├── inferencias.jsonl            # Auditoría de solicitudes
        └── supervision-rpc.jsonl        # Cambios/telemetría del watchdog
```

La ruta `~/llama.cpp` es un repositorio de tercero y no debe mezclarse con la autoría del proyecto en GitHub. Registrar revisión y comando de construcción, pero no incorporar automáticamente los pesos GGUF al repositorio académico.

## 12.2. Orange Pi Worker

```text
/home/orangepi/
├── llama.cpp/
│   └── build/bin/ggml-rpc-server
├── edgevision-camera/
│   ├── camera_service.py
│   ├── start.sh
│   ├── requirements.txt
│   ├── .venv/
│   └── models/yolo11n.onnx
├── edgevision-worker-metrics.py         # Servicio 9100
├── edgevision-rpc-observer-2051.py      # Servicio 9101
├── edgevision-start204/
│   └── scripts/esperar_ip.sh
└── edgevision-respaldos/                # Respaldos generados por parches
```

Unidades `systemd` esperadas en `/etc/systemd/system/`:

```text
edgevision-rpc.service
edgevision-camera.service
edgevision-metrics.service
edgevision-rpc-observer.service
```

El nombre exacto de alguna carpeta `.venv` o ruta de registros puede variar por historial de parches; usar `systemctl cat`/`find` para comprobar el equipo real, sin reescribir rutas a ciegas.

## 12.3. Estructura de repositorio GitHub propuesta

```text
EdgeVision_Repo/
├── ubuntu/edge-vision-lab/               # Fuentes y scripts propios
├── orangepi/
│   ├── edgevision-camera/                # Worker cámara
│   ├── edgevision-worker-metrics.py
│   ├── edgevision-rpc-observer-2051.py
│   └── systemd/                          # Unidades y configuración
├── docs/
│   ├── index.html                       # Página académica estática
│   ├── arquitectura.md
│   └── evidencias-publicas/              # Solo capturas aptas para publicar
├── README.md
├── .gitignore
└── VERSION_LLAMA_CPP.txt
```

**REPORTADO/IMPLEMENTADO:** se preparó el kit `EdgeVision_Kit_Codigo_GitHub_y_Web_Publica.zip`, con `Exportar-Codigo-EdgeVision.bat`, `Validar-RPC-EdgeVision.bat` y `docs/index.html`. No se ha confirmado todavía que la exportación y publicación del repositorio se hayan ejecutado.

---

# 13. Puesta en marcha y operaciones cotidianas

## 13.1. Orden operativo recomendado

1. Encender switch, conectar CAT6 y encender Orange Pi con webcam USB.
2. Arrancar laptop Windows 11 y la VM Ubuntu en VirtualBox.
3. Confirmar que las IP privadas estén presentes y la red funcione.
4. Esperar `systemd` de Orange Pi: RPC, cámara, métricas y observador.
5. Iniciar el portal Ubuntu si no está activo. El proyecto contiene `scripts/start.sh` y un BAT de inicio.
6. Desde Windows abrir `http://127.0.0.1:18000/`.
7. Esperar disponibilidad Qwen3-VL y elegir `RPC + VM` solo si Worker confirmado.
8. Probar cámara o imagen, y registrar resultado.

## 13.2. Comandos seguros de diagnóstico

### Windows PowerShell

```powershell
ssh -p 2222 milo@127.0.0.1
# Abrir en navegador: http://127.0.0.1:18000/
```

### Ubuntu

```bash
ip -4 -br addr
ping -c 4 192.168.100.20
bash ~/edge-vision-lab/scripts/status.sh
curl --noproxy '*' -fsS http://127.0.0.1:8000/api/status
ps -ww -C llama-server -o pid,args
sudo ss -ltnp | grep -E ':8000|:8081'
tail -n 5 ~/edge-vision-lab/evidencias/inferencias.jsonl
```

### Orange Pi

```bash
ip -4 -br addr show end0
systemctl is-enabled edgevision-rpc edgevision-camera edgevision-metrics edgevision-rpc-observer
systemctl is-active edgevision-rpc edgevision-camera edgevision-metrics edgevision-rpc-observer
curl --noproxy '*' -fsS http://192.168.100.20:9200/status
curl --noproxy '*' -fsS http://192.168.100.20:9100/metrics
curl --noproxy '*' -fsS http://192.168.100.20:9101/rpc-health
sudo journalctl -u edgevision-rpc -u edgevision-camera -u edgevision-metrics -u edgevision-rpc-observer -n 80 --no-pager
```

**No utilizar `nc`/`telnet`/`--list-devices` para sondear `50052` mientras el VLM distribuido trabaja.** La supervisión 2.0.5.1 está diseñada precisamente para no interferir con la conexión persistente RPC.

## 13.3. Cambio manual de modo

- En el portal, **Reactivar RPC** solo con análisis inactivo y el observador confirmando listener disponible.
- En el portal, **Usar solo VM** para respaldo o prueba de CPU local; puede tardar minutos en recargar pesos.
- No pulsar repetidamente los botones durante la transición.

## 13.4. Cómo consultar registros por sesión

```bash
cd ~/edge-vision-lab
# Solicitudes completadas:
tail -n 5 evidencias/inferencias.jsonl
# Transiciones/alarma del controlador:
tail -n 30 evidencias/supervision-rpc.jsonl
# Inicio y asignación de dispositivos:
grep -Ei 'start mode=|session_id=|RPC0|assigned to device|compute buffer' evidencias/modelo-vlm.log | tail -n 80
```

Para acreditar una solicitud concreta, el criterio correcto es **relacionar el identificador de sesión** del JSONL con el encabezado y las capas del log, no comparar líneas aisladas de distintas horas.

---

# 14. Instalación inicial y cronología de evolución

## 14.1. Secuencia general desde cero

1. Montaje Orange Pi, alimentación, almacenamiento y Debian Bookworm ARM64.
2. Instalación de utilidades SSH, compilación, monitoreo y herramientas de red.
3. Creación de VM Ubuntu Server AMD64 sobre VirtualBox Windows 11 (3 vCPU, RAM ajustada al anfitrión).
4. Corrección de adaptador puente de Wi-Fi a **Realtek Ethernet**; segundo adaptador NAT.
5. Configuración de subred interna `192.168.100.0/24`, comprobación de ping y SSH.
6. Compilación de `llama.cpp` con RPC en x86-64 y ARM64.
7. Prueba de texto con Qwen2.5-0.5B Q4; medición con y sin RPC.
8. Descarga de Qwen3-VL Q4 y proyector `mmproj` Q8; portal FastAPI.
9. Integración YOLO11-Nano, cámara USB, streaming y captura.
10. Correcciones de checksum ONNX, soporte de entrada 480 × 640 y flujo de análisis de fotograma.
11. Migración de procesos críticos de Orange Pi a `systemd` y creación de monitor de métricas.
12. Persistencia de IP (Netplan/NetworkManager) y reenvío NAT desde Windows.
13. Mejora del watchdog RPC mediante observación pasiva independiente en 2.0.5.1.
14. Preparación de documentación, presentación, validación RPC y exportador de código para GitHub.

## 14.2. Historial técnico resumido

| Revisión | Cambio | Incidencia/corrección |
|---|---|---|
| **Prueba inicial** | Linux + red + `llama.cpp` RPC + Qwen2.5. | Se corrigió el objetivo inexistente `ggml-rpc-server` habilitando `GGML_RPC=ON` y recompilando el binario. |
| **1.0** | Portal FastAPI y Qwen3-VL con respaldo local. | Primera inferencia multimodal requería validar el equipo real. |
| **2.0** | Webcam USB, YOLO11-Nano, ONNX Runtime y portal unificado. | El hash ONNX original y la expectativa de entrada cuadrada impedían el inicio. |
| **2.0.1** | Corrección de SHA-256 del ONNX. | Modelo validado, pero se detectó forma `1×3×480×640`. |
| **2.0.2** | Soporte ONNX rectangular, letterbox y coordenadas adaptativas. | Webcam/YOLO pasó a funcionar. |
| **2.0.3** | Reparación del flujo captura → Qwen3-VL y reintento local. | Se obtuvo análisis completo desde cámara, inicialmente con respuestas repetitivas. |
| **2.0.4** | Arranque persistente RPC/YOLO/métricas con systemd. | Monitor CPU/RAM `9100` pasó a visualizarse. |
| **2.0.5** | Intento de corregir watchdog cambiando monitor existente. | Instalador falló al verificar el monitor y **revirtió** el archivo, sin alterar RPC/YOLO. Causa fina no confirmada por diagnóstico incompleto. |
| **2.0.5.1** | Observador RPC pasivo dedicado `9101`; cambio de backend y estado UI. | El modo `RPC + VM` se observó estable y la inferencia del automóvil terminó. **Certificación por sesión todavía pendiente.** |

**Precaución de versiones:** no ejecutar instaladores antiguos sobre 2.0.5.1: pueden restaurar lógica de watchdog anterior. La revisión 2.0.5.1 tiene instalador, diagnósticos y reversión específicos.

---

# 15. Resultados experimentales y evidencia

## 15.1. Benchmark inicial del modelo de texto

| Prueba | Resultado compartido | Comentario |
|---|---:|---|
| Qwen2.5-0.5B solo CPU Ubuntu | **10.4 tokens/s** | Respuesta correcta en texto. |
| Qwen2.5-0.5B con backend RPC | **8.6 tokens/s** | Aproximadamente 17.3% menos tokens/s por overhead de comunicación/coordinación. |
| Asignación remota | `RPC0` con capas remotas | Se observaron buffers de cómputo remoto y de CPU. |
| CPU cómputo remoto en prueba inicial | **~33.01 MiB** | Memoria de cómputo, no RAM total de Orange Pi. |
| CPU cómputo Ubuntu en prueba inicial | **~38.27 MiB** | Memoria de cómputo local. |

**Conclusión del benchmark:** el reparto entre arquitecturas fue demostrable, pero el procesamiento distribuido no necesariamente acelera un modelo pequeño. Los costos de red y sincronización pueden superar cualquier ganancia.

## 15.2. Medición de YOLO webcam

- Dispositivo: `/dev/video0`.
- FPS medidos: **1.26** en la captura de estado disponible.
- Inferencia ONNX reportada: **337.0 ms**.
- Servicio HTTP: `online: true`, sin error reciente en esa medición.

## 15.3. Inferencia multimodal local

- Fotografía de un gato: respuesta correcta y coherente (naranja, ojos, bigotes, fondo); **245.38 s** en una prueba local y **240.8 s** en otra prueba.
- Fotograma de webcam: Qwen3-VL interpretó parcialmente una persona, con problemas de repetición textual en una prueba anterior; la integración de captura y análisis funcionó.
- Fotografía de un automóvil deportivo blanco junto a la costa: se observó texto generado y modo de interfaz **`RPC + VM`** tras el parche 2.0.5.1. **Falta registrar/correlacionar `rpc-primary` + `model_session_id` + capas RPC0 en esa misma solicitud**.

No deben calcularse mejoras de velocidad entre local y RPC del automóvil mientras no tengamos una medición comparable y certificada.

## 15.4. Reinicio y ausencia de Internet

**REPORTADO POR EL OPERADOR:** se realizaron las pruebas de reinicio y de inferencia sin Internet. Para cierre académico conservar:

- IP privada de ambos nodos tras arrancar.
- Estado `enabled`/`active` de cuatro unidades del Worker.
- Captura del navegador o registros de una solicitud durante desconexión WAN sin cortar Ethernet privado.
- Fecha, procedimiento y resultado reproducible.

---

# 16. Seguridad, publicación y propiedad del código

## 16.1. Riesgos y controles actuales

| Riesgo | Estado / mitigación |
|---|---|
| Exposición pública de RPC experimental | **Prohibido** abrir `50052` a Internet. Aislar en LAN. |
| Portal sin cuentas ni autenticación | Uso solo laboratorio. Si se publica dinámicamente, requerir autenticación y límites. |
| Webcam y captura accesible por red | Mantener `9200` en LAN privada y revisar permisos/privacidad. |
| Observadores/métricas sin autenticación | `9100/9101` limitados a LAN. |
| Fotogramas y prompts en registros | Revisar información sensible antes de compartir `evidencias`. |
| Contraseñas en GitHub | Excluir `.env`, llaves SSH, tokens, archivos de respaldo y revisar código manualmente. |
| Integridad de modelo ONNX | Validación SHA-256 específica de la revisión instalada; no deshabilitarla por conveniencia. |
| Dependencias y modelos de terceros | Registrar versiones y cumplir licencias del código/modelos. |

## 16.2. Dos modalidades de publicación web distintas

**Sitio académico estático:** `docs/index.html` a **GitHub Pages** o `index.html` a **Netlify Drop**. Publica descripción, arquitectura, videos y evidencias. **No ejecuta IA**, porque GitHub Pages/Netlify Drop no lanzan tu backend Python ni los modelos GGUF.

**Portal interactivo real:** para que terceros consulten el VLM desde Internet hacen falta Windows/Ubuntu encendidos, red disponible, un acceso HTTPS autenticado (por ejemplo Cloudflare Tunnel + Access), control de subida de archivos y limitación de solicitudes. **No se recomienda publicarlo ahora tal como está**, ni abrir el RPC/YOLO directamente.

## 16.3. Exportación a GitHub

Se generó un kit que recupera fuentes de `/home/milo/edge-vision-lab` y de la Orange Pi por SSH y prepara `EdgeVision_Repo`, sin copiar los grandes archivos GGUF/ONNX o los entornos virtuales.

Publicar como **repositorio privado inicialmente**. Revisar licencias y contenido; después abrirlo públicamente si procede. El repositorio académico debe documentar el upstream de `llama.cpp`, no adjudicarse su autoría ni incluir secretos.

---

# 17. Verificación y pruebas de aceptación

| ID | Requisito / prueba | Criterio de aceptación | Estado según evidencia actual |
|---|---|---|---|
| T01 | Arquitectura física | Laptop, switch CAT6, Orange Pi y webcam físicamente montados. | **VERIFICADO** por desarrollo y video/capturas del laboratorio. |
| T02 | Red privada | `192.168.100.10 ↔ 192.168.100.20` sin pérdidas; SSH operativo. | **VERIFICADO** ping 4/4 y SSH. |
| T03 | IP permanentes | Ambas IP reaparecen tras reinicio sin comandos `ip addr add`. | **REPORTADO** reinicio probado; conservar salidas. |
| T04 | Arranque de Worker | RPC, cámara, métricas y observador habilitados y activos tras reinicio. | **PARCIAL/REPORTADO**; capturas de versión reciente muestran servicios disponibles. |
| T05 | Inferencia de texto local | Qwen2.5 responde. | **VERIFICADO**. |
| T06 | RPC del SLM | Capas `RPC0` y resultado en prueba de texto. | **VERIFICADO**. |
| T07 | Webcam + YOLO | `online: true`, transmisión y detección física. | **VERIFICADO**. |
| T08 | Fotograma → VLM | La webcam entrega imagen y Qwen3-VL completa respuesta. | **VERIFICADO**; calidad mejoró con imágenes iluminadas. |
| T09 | Modelo VLM local | Respuesta coherente en `Solo VM`. | **VERIFICADO** foto del gato. |
| T10 | Qwen3-VL distribuido | Misma solicitud con `rpc-primary`, `session_id` y asignación/buffers RPC0. | **PENDIENTE DE CERTIFICACIÓN**. |
| T11 | Observación no intrusiva | Caída temporal `9101` no corta inferencia ocupada. | **IMPLEMENTADO**; capturas muestran aviso «sin confirmar» durante inferencia. |
| T12 | Caída real de Worker | Parar RPC; respaldo local genera nueva respuesta y se restablece servicio. | **PENDIENTE** cierre de prueba controlada/evidencias. |
| T13 | Sin Internet | WAN desconectada, LAN viva, YOLO/VLM responden. | **REPORTADO** como completado. |
| T14 | Monitoreo | CPU/RAM de ambos nodos, FPS y modo visibles. | **VERIFICADO** mediante capturas. |
| T15 | Publicación GitHub | Repo fuente sin secretos, modelos ni venv. | **PENDIENTE** confirmación de exportación/push. |
| T16 | Feria/sitio web | URL pública estática con resumen, video e informe. | **PENDIENTE** publicación. |
| T17 | Documentación académica | Informe PDF, defensa individual y grupal, reflexión, coevaluación. | **PENDIENTE** formalización/envío. |

### 17.1. Ejecución de comprobación RPC (preferente)

En Windows, desde el kit de publicación/exportación, ejecutar:

```text
Validar-RPC-EdgeVision.bat
```

Su salida `resultado_rpc.txt` debe reflejar la última solicitud `rpc-primary`, un `model_session_id` real y asignaciones remotas de la **misma sesión**. Si indica `vm-fallback`, la imagen se ejecutó por respaldo local y no puede presentarse como multimodal distribuida.

---

# 18. Requerimientos académicos y entregables

## 18.1. Referencia al PDF oficial y clase

Documento: **«Especificaciones generales del proyecto final integrador»**, título general **«Diseño, Montaje e Implementación de un Clúster de Edge Computing para Inferencia de IA Local Autónoma»**.

- Ponderación: **20 puntos**; informe técnico grupal **10 puntos** y defensa individual/video y coevaluación **10 puntos**.
- Equipos de **máximo cuatro integrantes**.
- Un **informe técnico formal en PDF** por equipo cargado en Canvas por el coordinador.
- Un **video de defensa individual de 5–7 minutos** por estudiante, según el PDF.
- La conversación de clase también contempló material grupal para feria virtual, demostración breve, reflexión y evaluaciones; verificar siempre la consigna vigente en Canvas.
- Arquitectura de red local privada con IP internas y comunicación mediante Gigabit Ethernet.
- Un caso elegible del documento es **visión por computadora con YOLO-Nano/MobileNet y cámara física**. EdgeVision cubre el caso con webcam + YOLO y añade Qwen3-VL como capacidad multimodal explicada en clase.
- El PDF menciona redundancia física/alta disponibilidad; el proyecto tiene **un solo switch** y respaldo lógico en CPU local, por lo que **no debe afirmar** redundancia física de red.
- La rúbrica impresa incluye descriptores sobre pfSense y portal cautivo que no equivalen a componentes implementados en EdgeVision; justificar el alcance de la solución según las aclaraciones del catedrático, sin atribuir una instalación de pfSense inexistente.

## 18.2. División propuesta de exposición

| Integrante | Sector | Contenido central |
|---|---|---|
| **1** | Problema/Edge Computing/hardware | Necesidad empresarial, autonomía local, Orange Pi, laptop, switch/cámara, limitaciones. |
| **2** | Infraestructura/sistemas/red | Debian, Ubuntu/VirtualBox, IP, SSH, interfaces, NAT/puente, systemd y puertos. |
| **3** | IA/RPC y pruebas | Cuantización, GGUF, Qwen2.5 y Qwen3-VL, mmproj, capas RPC, benchmarks y criterio de certificación. |
| **4** | YOLO/portal/failover | ONNX, V4L2, MJPEG, captura, API, monitoreo, respaldo y demostración. |

## 18.3. Materiales académicos a entregar/publicar

- [ ] Informe técnico final en PDF revisado por el equipo.
- [ ] Video individual de defensa por cada uno de los cuatro integrantes (5–7 min, según PDF).
- [ ] Video grupal breve y demostración para feria, conforme a la clase/Canvas.
- [ ] Video de reflexión/aprendizajes, según consigna de clase.
- [ ] Autoevaluación y valoración de pares utilizando la plantilla oficial.
- [ ] Capturas y logs suficientes para demostrar red, YOLO, VLM, RPC y recuperación.
- [ ] Repositorio del código fuente y referencia a licencias/dependencias.
- [ ] Página académica pública o enlace de presentación con permisos comprobados.

---

# 19. Limitaciones conocidas y mejoras futuras

1. **Modelo distribuido VLM todavía no certificado:** existe evidencia de carga/ruta `RPC + VM` y respuesta, pero falta correlación `rpc-primary` de la misma sesión con capas RPC0.
2. **Inferencia lenta por CPU:** una fotografía puede tardar varios minutos; la cámara opera con FPS bajos.
3. **Observación pasiva no es una medición de trabajo:** el listener abierto no demuestra cálculos ejecutados.
4. **Failover en frío:** tiempo de recarga y nueva solicitud; no continuidad sin interrupción.
5. **Punto único de fallo físico:** un solo switch y una sola Orange Pi.
6. **Sin autenticación web para Internet:** limitar el portal y los servicios a LAN; publicar solo micrositio estático o incorporar acceso autenticado antes de habilitar consulta remota.
7. **Configuración dependiente de versiones:** compatibilidad `llama.cpp` RPC/VLM, modelo GGUF, formato `mmproj`, revisión ONNX y APIs debe preservarse mediante hashes/versiones.
8. **Sin medición académica exhaustiva de calidad:** preparar ejemplos positivos/negativos, tasa de detección con distintas condiciones de luz, latencia y comparación local vs RPC VLM en escenarios reproducibles.
9. **Escalabilidad:** futuro Worker adicional, balanceador, aislamiento por VLAN, autenticación y TLS, monitoreo histórico y pipeline CI.

---

# 20. Próximas acciones priorizadas

**P0 — Certificar RPC multimodal sin modificar componentes:** ejecutar `Validar-RPC-EdgeVision.bat` sobre la última inferencia de automóvil o repetir una fotografía con el modo estable; conservar `resultado_rpc.txt`, la imagen, el `request_id` y el log de la misma sesión.

**P1 — Completar evidencia de caída controlada:** detener solo RPC cuando el sistema está ocioso, observar recuperación a `Solo VM`, completar nueva inferencia y restaurar RPC.

**P2 — Cerrar bitácora offline y reinicio:** reunir comandos/capturas de IP, servicios y respuestas sin WAN correspondientes a las pruebas reportadas.

**P3 — Publicar fuentes y sitio de feria:** revisar exportación, limpiar secretos, subir GitHub privado, publicar micrositio estático con evidencias y presentación, confirmar permisos de links.

**P4 — Entrega formal:** actualizar informe/presentación con resultados 2.0.5.1, generar PDF y completar videos y evaluaciones de integrantes.

---

# 21. Referencias de implementación y fuentes del proyecto

Archivos fuente/artefactos utilizados para reconstruir esta especificación:

- `EdgeVision_2_0_5_1_Correccion_RPC_Sin_Tocar_Monitor_9100.zip` — lógica de `backend/engine.py`, `backend/main.py`, observador RPC pasivo y scripts de instalación.
- `EdgeVision_2_0_4_Arranque_Permanente_y_Monitoreo.zip` — unidades `systemd` del Worker, monitor 9100, rutas y verificaciones.
- `EdgeVision_2_0_2_Parche_Camara_YOLO_Rectangular.zip` — corrección de tamaño de entrada ONNX rectangular.
- `EdgeVision_2_Camara_USB_YOLO_Nano_Actualizacion.zip` — backend de cámara, interfaces y dependencias.
- `EdgeVision_Fase_Final_Multimodal_Automatizada.zip` — aplicación inicial VLM con respaldo local.
- `EdgeVision_Kit_Codigo_GitHub_y_Web_Publica.zip` — exportación de fuentes, validación RPC y micrositio.
- `proyecto final requerimientos.pdf` — restricciones oficiales, ponderación y entregables académicos.
- `class.txt` — transcripción compartida de la explicación del catedrático.
- Capturas y registros de terminal/portal compartidos durante el laboratorio.

Referencias de software y documentación de terceros:

- `llama.cpp`: https://github.com/ggml-org/llama.cpp
- Orange Pi 4 Pro, soporte oficial: https://www.orangepi.org/html/hardWare/computerAndMicrocontrollers/service-and-support/Orange-Pi-4-Pro.html
- FastAPI: https://fastapi.tiangolo.com/
- ONNX Runtime: https://onnxruntime.ai/
- OpenCV: https://opencv.org/
- GitHub Pages: https://docs.github.com/en/pages
- Exportación YOLO11n ONNX de referencia: https://huggingface.co/unileon-robotics/YOLO11-ONNX

---

## Anexo A — Información mínima para transferir a otro desarrollador o agente de código

```yaml
project: EdgeVision
current_version: 2.0.5.1
reference_date: 2026-10-16
architecture: offline-first-edge-ai
host:
  os: Windows 11
  ram_gb: 16
  cpu_cores_reported: 6
  hypervisor: VirtualBox
master:
  os: Ubuntu Server 24.04 LTS x86_64
  user: milo
  lan_ip: 192.168.100.10
  lan_interface: enp0s3
  nat_interface: enp0s8
  vm_vcpus: 3
  vm_ram: "~8 GiB observed; verify actual VM allocation"
  ssh_from_windows: "ssh -p 2222 milo@127.0.0.1"
  portal_from_windows: "http://127.0.0.1:18000/"
  project_root: /home/milo/edge-vision-lab
  model_dir: /home/milo/edge-vision-models
  ports:
    web: 8000
    llama_server: 8081
worker:
  os: Debian 12 Bookworm aarch64
  user: orangepi
  board: Orange Pi 4 Pro
  cpu_cores: 8
  ram_gb: 4
  lan_ip: 192.168.100.20
  lan_interface: end0
  secondary_ics_ip: 192.168.137.20
  ports:
    ggml_rpc: 50052
    camera_yolo: 9200
    cpu_ram_metrics: 9100
    rpc_observer: 9101
models:
  text_benchmark: Qwen2.5-0.5B-Instruct Q4_K_M GGUF
  vlm: Qwen3VL-2B-Instruct-Q4_K_M.gguf
  vision_projector: mmproj-Qwen3VL-2B-Instruct-Q8_0.gguf
  detector: yolo11n.onnx
vlm:
  runtime: llama.cpp/llama-server
  rpc_layers_configured: 8
  cpu_threads: 3
  context_tokens: 4096
  image_max_tokens: 512
  slots: 1
  fallback: cold-local-cpu
  inference_audit: /home/milo/edge-vision-lab/evidencias/inferencias.jsonl
  model_log: /home/milo/edge-vision-lab/evidencias/modelo-vlm.log
  rpc_distributed_certified: false
camera:
  device_seen: /dev/video0
  runtime: ONNX Runtime CPU + OpenCV
  onnx_input: [1, 3, 480, 640]
  target_fps: 1
  measured_fps_example: 1.26
  measured_inference_ms_example: 337.0
security:
  public_interactive_portal_authenticated: false
  internet_exposure_of_internal_ports_allowed: false
status:
  webcam_yolo: verified
  vlm_local_image: verified
  rpc_text: verified
  rpc_vlm_ui_stable_and_completed: observed
  rpc_vlm_session_certification: pending
  reboot_test: user_reported
  offline_test: user_reported
  worker_failover_controlled_test: pending_evidence
  github_publication: pending_confirmation
```

**Regla para continuar el desarrollo:** preservar el funcionamiento actual (webcam YOLO, VLM local, servicios `systemd`, modelo GGUF/ONNX y direccionamiento). Antes de aplicar cualquier nuevo parche, comparar hashes y versiones de archivos, respaldar los originales, no reiniciar RPC/YOLO si no es estrictamente necesario y verificar RPC sin conectarse activamente a `50052` durante una inferencia.
