Saltar al contenido principal

Desarrollo de páginas web en real-cugan-wasm

init-qydesarrollo front-endreal-cuganwasmAlrededor de 4 min

Aquí registro aproximadamente una semana de mi proceso de incrustación de páginas wasm en vuepress, que involucra muchos aspectos, incluyendo (git submoduleopen in new window,emscriptenopen in new window,naive-uiopen in new window,COOP-COEPopen in new window) la exploración y uso de estas tecnologías. Actualmente, esta página de herramientas está casi terminada y tiene una buena experiencia en el navegador Chrome.

Antecedentes

Por casualidad, me enteré de que Bilibili lanzó una herramienta de IA llamada Real-CUGANopen in new window y vi su implementación wasm en una página webopen in new window, así que se me ocurrió la idea de intentar incrustarla en vuepress y ponerla en mi propio blog.

Proceso

Esta implementación fue bastante compleja y encontré varios problemas que nunca había enfrentado antes, lo que me dio mucha experiencia. La implementación de todo el wasm se basó en gran medida en la lógica de realcugan-ncnn-webassemblyopen in new window, pero actualicé la parte de models-pro según realcugan-ncnn-webassemblyopen in new window. A continuación, registraré el proceso de uso y los problemas encontrados para cada una de las tecnologías utilizadas.

git submodule

El autor del repositorio realcugan-ncnn-webassemblyopen in new window en realidad no subió el git submodule, por lo que clonar directamente este repositorio y ejecutar git submodule update --init no funcionará y no se podrá determinar la versión del submodule. Por lo tanto, no pude usar la última versión de ncnn que se ejecutó y finalmente confirmé la versión según realcugan-ncnn-webassemblyopen in new window.

Al mismo tiempo, agregué emsdk al submodule, lo que me permitió configurar emscripten directamente en github action y completar el proceso de compilación posterior.

emscripten

Como esta vez no desarrollé completamente el wasm, solo realicé algunas actualizaciones y migraciones según el repositorio del experto, no tengo un profundo conocimiento de ello, solo hay tres puntos a tener en cuenta:

  • Es mejor especificar la versión de emscripten, ya que no estoy seguro si las nuevas versiones tienen actualizaciones destructivas y no encontré documentación detallada de las actualizaciones.
  • -sEXPORTED_FUNCTIONS especifica las funciones de salida y las expone en Module. Si encuentras _xxFun not defined, debes modificarlo en CMakeList.txt.
  • Es necesario borrar la caché de compilación, de lo contrario podrían surgir problemas inesperados.

Introducción de Unocss y Naive Ui

Unocss es relativamente simple y no he encontrado problemas de superposición de estilos, solo necesita ser configurado:

Unocss({
  mode: "per-module",
});

Naive Ui es un poco más complejo y requiere algunos pasos:

  • En primer lugar, no se puede utilizar el método de referencia automática de la serie unplugin para escribir el código, debe ser importado manualmente.
  • Luego, es necesario envolver el componente con el componente <ClientOnly> en el nivel más externo para omitir la compilación ssg.
  • Los componentes como message, dialog, etc., se utilizan a través de createDiscreteApi.
  • Por último, es necesario configurar el ssr para que se pueda compilar correctamente:
ssr: {
  noExternal: ['naive-ui', 'vueuc', 'date-fns'],
}

Estas configuraciones y su uso pueden parecer simples, pero en realidad detrás de cada conclusión hay muchos intentos. Puedes encontrar estas configuraciones en este repositorioopen in new window.

Uso de archivos wasm

Después de generar los archivos con emscripten, necesitamos colocarlos en la misma carpeta que los archivos de modelo para que puedan ser leídos y utilizados por estos modelos. Durante el desarrollo, tuve muchos problemas con la ubicación de lectura de estos archivos. El archivo js generado lee el modelo .bin utilizando una ruta relativa, y la ruta de mi página es /tools/realcugan-ncnn-webassembly.html, lo que significa que intentará obtener el archivo /tools/xxx.bin. Esto implica que debo colocar los archivos generados .js, .wasm, .bin en la carpeta public/tools.

Además, debido al soporte de i18n, no se puede leer el modelo .bin desde otra URL en inglés, como /en/tools/realcugan-ncnn-webassembly.html. Si esto fuera en mi propio servidor, sería fácil de solucionar, simplemente escribiría una redirección en nginx. Sin embargo, como mi sitio web está alojado en github.io, la forma más fácil y rápida de solucionar esto es colocar una copia completa de los archivos de recursos en la carpeta correspondiente. La desventaja es que ocupa más espacio de almacenamiento en el repositorio. En mi caso, utilicé un método muy "hack" para redirigirlo forzadamente a través de un "work server".

// do something Redirect
const pattern = /.+\/en\/tools\/.+\.(js|wasm|bin|param|data|jpg)$/;
if (pattern.test(request.url)) {
  request = new Request(request.url.replaceAll("/en/tools", "/tools"), {
    cache: request.cache,
    credentials: request.credentials,
    headers: request.headers,
    integrity: request.integrity,
    destination: request.destination,
    keepalive: request.keepalive,
    method: request.method,
    mode: request.mode,
    redirect: request.redirect,
    referrer: request.referrer,
    referrerPolicy: request.referrerPolicy,
    signal: request.signal,
  });
}

---Actualización del 2 de agosto de 2023---

emscripten tiene un método expuesto llamado locateFile, que permite redirigir los archivos cargados utilizando un CDN u otra URL. Por lo tanto, eliminé el método de redirección "hack".

locateFile: (path: string, prefix: string) => {
  return prefix.replace('/en/', '/') + path
},

No estoy seguro de cómo afecta el uso de wasm en múltiples páginas, pero tuve problemas al cambiar entre diferentes pestañas: onRuntimeInitialized solo se ejecuta una vez. Por lo tanto, utilicé la forma más conveniente, rápida y menos propensa a errores para resolver este problema: recargar la página al ingresar.
Esto puede ser confuso, pero es la mejor solución que se me ocurrió.

COOP-COEP

La política de mismo origen es una barrera impuesta por los navegadores, solo cuando el servidor firma el acuerdo mismo origen, puede proporcionarte un sharedbuffer. Aquí también se utiliza un método "hack" para que la aplicación wasm funcione correctamente, consultando coi-serviceworkeropen in new window. Debido a esto, esta herramienta solo se puede ejecutar en Chrome y Edge, consulta (https://caniuse.com/mdn-api_window_credentiallessopen in new window).

Próximos pasos

Con la experiencia de desarrollo de esta vez, en realidad hay muchas más cosas que se pueden hacer. Teóricamente, puedo desarrollar cualquier programa en el navegador sin preocuparme por las limitaciones de lenguaje o entorno. Tal vez haya una falta de velocidad de ejecución, pero como dice el refrán: "si funciona, está bien".

Este post está traducido usando ChatGPT, por favor feedbackopen in new window si hay alguna omisión.