v1.23.0: Rellenar (LaMa rellena lo pintado en el editor de revelado)

Para «Rellenar con IA» de Eliminar en Labstream OS: la página manda el trozo de la foto
alrededor de lo pintado, en 8 bits con el hueco en el alfa, y la app lo devuelve con el
hueco relleno por LaMa y lo demás byte a byte como estaba (src-tauri/src/ia/relleno.rs).

- Comando nuevo ia_rellenar (permitido solo para el origen de la app). ia_estado e
  ia_preparar llevan { que: "relleno" }; sin él siguen hablando del sujeto, como la 1.22,
  y el estado dice ahora de qué IA habla (así la página sabe que esta app rellena).
- LaMa (Apache-2.0) en la exportación ONNX de tamaño libre de g-ronimo, desde el servidor
  de la app con la sesión de la pestaña y fijada por huella (≈210 MB). Se rellena al
  tamaño del trozo en múltiplos de 32, con 1024 px de lado como mucho.
- En la CPU: las dos exportaciones de LaMa probadas fallan con DirectML en una RTX 5080
  (su FFT, sea el operador DFT o productos de matrices: 80070057, también con las formas
  fijadas y sin optimizar); en la CPU, ~3 s a 512 px y ~10 s a 1024, y no le quita
  memoria a la tarjeta.
- Las piezas por IA: el motor (ONNX Runtime + DirectML) es de las dos; cada modelo se baja
  cuando se usa la suya. Cada modelo abierto se suelta a los 2 min sin uso.

Pruebas nuevas: el tamaño al que se rellena y que fuera del hueco no cambia nada; y una de
punta a punta en este equipo (ignorada en CI).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Este commit está contenido en:
Munka
2026-10-14 20:17:54 -05:00
padre a725900a4a
commit eec48362e5
Se han modificado 13 ficheros con 393 adiciones y 68 borrados

Ver fichero

@@ -1,4 +1,6 @@
// ── Lo que la IA baja la primera vez (≈700 MB), de dónde, y con qué huella ──
// ── Lo que la IA baja la primera vez, de dónde, y con qué huella ──
// El motor (≈215 MB) es de las dos IA; cada modelo se baja solo cuando se usa la suya: el del sujeto
// (≈490 MB) o el de rellenar (≈210 MB).
//
// Fijado por versión y huella SHA-256 (comprobadas al bajarlo el 14-oct-2026): si algún día cambia
// lo que hay en esa dirección, no se usa.
@@ -11,6 +13,10 @@
// 5080: 0,3 s por foto y el mismo borde que el original en la CPU.
// El HR (2048 px, matting) se probó y NO va: su convolución deformable, deshecha en GatherND en la
// exportación oficial, ocupa 14–15 GB con DirectML y tarda de 6 a 45 s (14-oct-2026).
// - Rellenar (1.23): LaMa (Apache-2.0, advimman/big-lama), la exportación ONNX de tamaño libre de
// g-ronimo (Hugging Face g-ronimo/lama, `lama.onnx`, la que usa wipe.photos), copiada al servidor de
// la app (api/modelos/relleno-equipo). Entrada `input` [1, 4, alto, ancho] (múltiplos de 32),
// salida `output` [1, 3, alto, ancho], 0..1. Corre en la CPU (ver motor.rs: abrir_en_cpu).
// - ONNX Runtime 1.24.4 con DirectML (NuGet de Microsoft): onnxruntime.dll para x64.
// - DirectML 1.15.4 (NuGet de Microsoft): DirectML.dll para Windows x64 (el paquete trae también
// las de Xbox y las de depurar: se saca por su ruta exacta).
@@ -18,6 +24,8 @@
use super::bajar::{Forma, Pieza};
pub const NOMBRE_MODELO: &str = "BiRefNet";
pub const NOMBRE_RELLENO: &str = "LaMa";
pub const ARCHIVO_RELLENO: &str = "lama-g-ronimo-44bb92b2.onnx";
/// El lado de la entrada y de la salida del modelo.
pub const LADO: usize = 1024;
@@ -25,6 +33,38 @@ pub const ARCHIVO_MODELO: &str = "birefnet-general-epoch_244-fp16.onnx";
pub const DLL_ORT: &str = "onnxruntime.dll";
pub const DLL_DIRECTML: &str = "DirectML.dll";
/// De qué IA se habla: la máscara de sujeto o rellenar.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Que {
Sujeto,
Relleno,
}
impl Que {
pub fn de(v: Option<&str>) -> Que {
if v == Some("relleno") {
Que::Relleno
} else {
Que::Sujeto
}
}
pub fn nombre(self) -> &'static str {
match self {
Que::Sujeto => "sujeto",
Que::Relleno => "relleno",
}
}
}
static RELLENO: Pieza = Pieza {
nombre: "lama-g-ronimo-44bb92b2",
url: "https://os.labstreamsas.com/api/modelos/relleno-equipo",
sha256: "44bb92b2693db40bb088dda226365a3aa8080a561584b8b0287ab11a97f9e9e7",
bytes: 209_181_361,
forma: Forma::Archivo(ARCHIVO_RELLENO),
con_sesion: true,
};
static PIEZAS: [Pieza; 3] = [
Pieza {
nombre: "onnxruntime-directml-1.24.4",
@@ -52,6 +92,10 @@ static PIEZAS: [Pieza; 3] = [
},
];
pub fn todas() -> &'static [Pieza] {
&PIEZAS
/// Lo que necesita cada IA: el motor (los dos primeros) y su modelo.
pub fn de(que: Que) -> Vec<&'static Pieza> {
match que {
Que::Sujeto => PIEZAS.iter().collect(),
Que::Relleno => vec![&PIEZAS[0], &PIEZAS[1], &RELLENO],
}
}