Técnicas de one-liners de Bash para LLM
(justine.lol)- Usando llamafile, un proyecto open source creado junto con Mozilla, como si fuera una herramienta de shell, se pueden ejecutar LLM locales como un solo ejecutable y resolver tareas de imágenes, páginas web, API, chat, código y correo electrónico con one-liners de Bash
- Los
.llamafilebasados en LLaVA generan descripciones de imágenes en la salida estándar solo con--imagey un prompt, aunque según el sistema operativo puede hacer falta preparación como Xcode,binfmt_misco el sufijo.exe - Para integrarlo en automatizaciones, conviene acotar la salida con restricciones de gramática BNF,
--temp 0y límites de tokens con-n, y al generar nombres de archivo es importante evitar salidas impredecibles y erroresENAMETOOLONG - El resumen de URLs funciona convirtiendo HTML a texto con
linksy luego canalizándolo a un llamafile de Mistral 7B; en el ejemplo, una página web de 3,774 palabras se reduce a un resumen de 129 palabras - También permite usar una API local compatible con OpenAI, un chatbot de terminal, autocompletado de código y redacción de correos, pero los LLM para programación siguen teniendo límites en matemáticas y verificación, así que es más seguro verlos como herramientas de apoyo para explorar temas desconocidos
Usar llamafile como herramienta de shell para LLM locales
- llamafile es un proyecto open source trabajado junto con Mozilla que permite ejecutar LLM directamente en la computadora del usuario
- El proyecto consiguió 8.3k stars en GitHub, 1073 upvotes en Hacker News y también fue cubierto por Hackaday
- La versión de referencia en los ejemplos es la 0.8.12, y el artículo muestra qué se puede hacer con esa versión
- El inicio consiste en descargar un
.llamafileprecompilado desde Hugging Face y darle permisos de ejecución- El modelo usado es
llava-v1.5-7b-q4.llamafile, para el modelo multimodal de visión LLaVA - Puede ejecutarse en MacOS, Linux, Windows y BSD
- Si hay problemas, hay que revisar la sección Gotchas del README; en MacOS puede hacer falta Xcode, en Linux el intérprete
binfmt_misc, y en Windows el sufijo.exe
- El modelo usado es
Resumen de imágenes: llamar a LLaVA por salida estándar
llava-v1.5-7b-q4.llamafileusa por defecto un modelo multimodal de visión, aunque ese comportamiento cambia si se pasa--mmproj ''- Las imágenes se envían con la bandera
--image GRAPHIC, y acepta archivos jpeg, png, tga, bmp, psd, gif, hdr, pic y pnm - La pregunta se pasa como
--silent-prompt -p PROMPT, y la respuesta sale por la salida estándar - El one-liner de ejemplo le pregunta
What do you see?alemurs.jpgy usa--temp 0para obtener una salida determinista - Para offloading a GPU hace falta
-ngl 999 - El mismo comando de resumen de imagen puede variar mucho en tiempo de ejecución según el hardware
- Mac Studio: 4 segundos, precio $8,300, M2 Ultra, ancho de banda de memoria de 800 GB/s, 60 GPU cores
- Windows PC: 10 segundos, NVIDIA GeForce RTX 2080 Ti de hace 4 años, precio en Amazon en ese momento de $500~$1,000
- Hewlett Packard ProDesk 600 G5: 45 segundos, $1,653, Intel Core i9-9900, ancho de banda de memoria de 2667 MT/s o 19.8 GB/s, sin GPU
- La salida de ejemplo describe a una lémur hembra sosteniendo a dos de sus tres crías, brindándoles protección y calor en un entorno verde
Generación segura de nombres de archivo: restricciones gramaticales y límites de tokens
- Al crear nombres de archivo de imágenes con LLaVA, el riesgo principal es que la salida del LLM suele ser impredecible
--grammarrestringe los tokens de salida posibles usando Backus-Naur Form- Por ejemplo,
root ::= "yes" | "no"obliga a que la salida solo sea"yes\n"o"no\n" - En el ejemplo de nombres de archivo, primero se hace que solo salgan palabras en minúsculas y espacios, luego
sedreemplaza los espacios por guiones bajos y se agrega.jpg
- Por ejemplo,
- El one-liner para generar nombres de archivo usa
--grammar 'root ::= [a-z]+ (" " [a-z]+)+'junto con-n 16 - Si no se limita la cantidad máxima de tokens generados con
-n 16, el LLM puede producir texto demasiado largo y provocar un errorENAMETOOLONG - La gramática debe coincidir hasta cierto punto con la forma en que el modelo normalmente genera texto
- LLaVA no fue entrenado para producir frases con guiones bajos, así que si se meten guiones bajos directamente en la BNF pueden aparecer salidas inconsistentes
- La salida en minúsculas sí estaba dentro del rango natural de LLaVA
- Formatos muy presentes en la web, como JSON, pueden funcionar como guardrails con restricciones gramaticales para reducir errores sintácticos en JSON alucinado
- Como versión más completa, se menciona el script
rename-pictures.sh, con un ejemplo ejecutado sobre~/Pictures
Resumen de URLs: combinación de links y Mistral 7B
- Mistral 7B instruct llamafile puede usarse para resumir URLs HTML canalizando la salida del comando
links linkses un navegador web de línea de comandos y en MacOS normalmente puede instalarse conbrew install links- También se ofrece un binario APE precompilado para usar cuando no hay gestor de paquetes
linksv2.29, 7.7MB- Para AMD64+ARM64, Linux+Windows+FreeBSD+NetBSD+OpenBSD
- El one-liner de resumen de URL funciona con este flujo
- Primero imprime
[INST]Summarize the following text: - Convierte la página web a texto con
links -codepage utf-8 -force-html -width 500 -dump URL - Limpia algunos caracteres con
sed 's/*/ /g' - Agrega
[/INST]y luego lo envía al llamafile de Mistral con-f /dev/stdin
- Primero imprime
- La página de ejemplo, “Real Programmers Don’t Use Pascal”, se reduce de 3,774 palabras a un resumen de 129 palabras
- Con el mismo método también se pueden hacer preguntas arbitrarias sobre un texto
- En el ejemplo, se pregunta si el autor parece mentalmente inestable, y Mistral responde teniendo en cuenta que, aunque hay exageración e hipérbole, se trata de un texto satírico de 1983
- Si se usa
--grammar 'root ::= "yes" | "no"', la salida puede limitarse a una forma YES/NO más fácil de usar en scripts
- La restricción importante es no superar el contexto de 32k tokens de Mistral v0.2
-width 500ayuda a evitar la recomposición de párrafos y reduce saltos de línea innecesariossed 's/ */ /g'puede reducir espacios repetidosdd bs=1 count=80000puede servir como último recurso para recortar páginas web largas de forma brusca
API local compatible con OpenAI
- El llamafile “server” ofrece un endpoint local compatible con la API de OpenAI
- El ejemplo usa Mixtral 8x7B y requiere una GPU potente capaz de ejecutar un modelo de 30 gibibytes
- El servidor se inicia con
mixtral-8x7b-instruct-v0.1.Q5_K_M-server.llamafile --nobrowser - En otra terminal, se hace una solicitud con
curlahttp://localhost:8080/v1/chat/completionsy luego se usa Python para imprimir el JSON de respuesta de forma legible - El JSON de la solicitud sigue el formato de OpenAI Chat Completions, con
modelpuesto comogpt-3.5-turboy un arreglo de mensajes system y user - La respuesta de ejemplo incluye un mensaje
assistantque explica en verso el concepto de recursión, junto con el uso decompletion_tokens,prompt_tokensytotal_tokens
Chatbot de terminal: prompt Digital Athena
- llamafile puede usarse como una herramienta estándar de línea de comandos UNIX descargando el binario comprimido desde la página de lanzamientos o compilándolo desde el código fuente
- Se muestra el flujo
git clone,make -j8,sudo make install,man llamafile
- Se muestra el flujo
- Esto facilita su uso junto con los GGUF weights de Hugging Face
- El ejemplo de chatbot usa el modelo LLaMA original publicado por Facebook con fines de investigación
- Es importante diseñar el prompt para que hable con tono académico y sin antropomorfizar el modelo
- El nombre Digital Athena viene de Atenea, la diosa griega de la sabiduría y el conocimiento
- Empieza con un formato de diálogo entre
ResearcheryDigital Athena
- Para la ejecución interactiva se usan opciones como
--interactive,--color,--ctx_size 4096,--reverse-prompt 'Researcher:' --temp 0hace que la salida sea determinista y reproducible- Si no se usa, llamafile aplica el nivel de aleatoriedad de la versión 0.8.12 y se obtiene una respuesta distinta cada vez
- Si se quiere un chatbot antropomorfizado, el modelo LLaMA original puede ser difícil de manejar porque su tendencia por defecto es tratar al usuario como si fuera un desconocido en Reddit
Autocompletado de código: uso de Wizard Coder
- Al descargar Wizard Coder llamafile, se puede usar para autocompletar la línea actual en Emacs o Vim
- El modelo de ejemplo está ajustado principalmente para Python, pero genera una implementación en C de
memcpy() - El prompt solo incluye el inicio de un bloque de código Markdown y la firma de la función, sin explicación en inglés
- Si no se usa inglés, disminuye la probabilidad de que el modelo agregue largas explicaciones sobre el código
- Si se usan bloques de código Markdown, es más probable que aparezca el token de reverse prompt definido con
-ry que termine en el momento adecuado - Para forzar una detención más clara, también se puede limitar la respuesta a 100 tokens con
-n 100
- La salida de ejemplo implementa
memcpy()con un bucleforque copiasizedesdesrcadsty devuelvedst - Los LLM para programación tienen límites evidentes
- Entienden bien el lenguaje humano, pero son débiles en matemáticas
- Escriben código que parece convincente, pero muchas veces no resiste una revisión cuidadosa
- Puede ayudar pensarlos como herramientas que repiten respuestas de Stack Overflow en varios lenguajes
- Para tener una buena experiencia, conviene usarlos como apoyo para explorar temas desconocidos
Redacción de correos: generar respuestas con modelos pequeños
- El ejemplo de redacción de correos plantea un escenario donde una Raspberry Pi de $50 responde correos corporativos para ayudar a vender productos
- Rocket 3B usa una sintaxis de prompt ligeramente distinta y, en este caso, la temperature puede ayudar a imitar cierta improvisación
- El ejemplo asume una configuración en la que un servidor PHP inyecta solicitudes de soporte en el prompt y canaliza la salida a
sendmail - El prompt de sistema indica que debe ayudar al usuario, pero llevando la conversación hacia la compra de pepinillos
- En el ejemplo, cuando un usuario dice que necesita rescate tras encontrarse con vientos fuertes en Long Island Sound, el modelo genera una respuesta empática y luego recomienda Bill Pickle’s Gourmet Dill Pickles
- El último ejemplo tiene intención humorística y no debe interpretarse como una recomendación o respaldo de Mozilla hacia ningún modelo, licencia, dataset o práctica específicos
1 comentarios
Opiniones en Hacker News
Desde hace varios meses vengo explorando con gusto la combinación de LLM y utilidades de CLI, y realmente encajan muy bien
La forma de la filosofía Unix de encadenar varias herramientas con pipes también se lleva muy bien con la manera en que funcionan los LLM
He experimentado principalmente con la herramienta de CLI https://llm.datasette.io/, y también hay herramientas de uso puntual como https://github.com/simonw/blip-caption y https://github.com/simonw/ospeak
Es tan divertido que me sorprende que más gente no esté explorando a fondo el área de LLM+CLI
Ha sido la exploración más ruidosa que he visto hasta ahora en el campo tecnológico, al punto de que no necesito oír más, sino más bien menos
Expone plantillas de prompts como verbos de línea de comandos y puede cargarlas desde varios “repositorios”
Mantengo un conjunto de prompts para cada repositorio en el que trabajo, junto con scripts “prompto” personalizados https://github.com/go-go-golems/prompto que generan contexto dinámico para prompts
También hice varios para bibliotecas de terceros, que están en https://github.com/go-go-golems/promptos
Algunos prompts públicos se pueden ver en https://github.com/go-go-golems/geppetto/tree/main/cmd/pinoc..., y ahora estoy creando un framework declarativo de agentes
Hace poco, con httrack + w3m dump + sgpt images + visión de GPT, construí una base de conocimiento específica de 278 mil tokens, y armé un RAG con un hack personalizado en Perl que preserva la estructura general del conocimiento
Me pregunto si han visto herramientas que encajen bien con la filosofía Unix para el procesamiento de entrada y RAG local
Por cierto, veo que el autor del post original ya hizo bastante trabajo relacionado y lo resumió en https://simonwillison.net/2023/Oct/23/embeddings/
Donde ahora estoy trabado es en una cadena de herramientas para hacer chunking del contenido del que se crearán embeddings. Sería bueno que hiciera cosas como detectar contexto de ubicación en el texto original, tipo “2.1 Failover” o “Chapter 8: The dream”, deshacer saltos de línea de fuentes con ancho de 80 caracteres y dividir de forma inteligente preservando los párrafos
Creo que la causa principal es VS Code, y los desarrolladores a los que doy soporte también prefieren más apuntar y hacer clic que la terminal y la CLI
Posts recientes relacionados
Llamafile – The easiest way to run LLMs locally on your Mac - https://news.ycombinator.com/item?id=38522636 - diciembre de 2023, 17 comentarios
Llamafile is the new best way to run a LLM on your own computer - https://news.ycombinator.com/item?id=38489533 - diciembre de 2023, 47 comentarios
Llamafile lets you distribute and run LLMs with a single file - https://news.ycombinator.com/item?id=38464057 - noviembre de 2023, 287 comentarios
Muy bueno. Me gustó especialmente el ejemplo de renombrar archivos de imagen de forma descriptiva con un LLM
Lo probé en una desktop Windows con una NVIDIA GeForce RTX 3080 Ti, y hubo algunos obstáculos antes de lograr que funcionara
WSL muestra el error
error: APE is running on WIN32 inside WSL. You need to run: sudo sh -c 'echo -1 > /proc/sys/fs/binfmt_misc/WSLInterop', que en el one-liner queda oculto en/dev/nullDespués, en zsh apareció
zsh: exec format error: ./llava-v1.5-7b-q4-main.llamafile, así que tuve que ejecutarlo en bash. Es cierto que el título dice bash, pero parece raro que no funcione en zshTambién aparece una advertencia de que no se admite el offloading a GPU, probablemente por WSL. No hago programación de GPU en esta máquina Windows
shal comando:sh ./llava-v1.5-7b-q4-main.llamafileEs un comportamiento particular de zsh y APE, y hay contenido relacionado en https://justine.lol/ape.html
Me pregunto si la prueba fue muy lenta usando solo CPU
Al buscar rápidamente en Hugging Face, veo varios Llamafile de TinyLlama de alrededor de 1B
Sumados a los 3 llamafile que ya había, serían 6 en total, pero me pregunto si hay otros llamafile más por ahí
Me pregunto qué opina HN de llamafile y modelfile(https://github.com/jmorganca/ollama/blob/main/docs/modelfile...)
Ambos me recuerdan a una experiencia tipo Dockerfile. Modelfile se ve directamente como un Dockerfile, pero llamafile parece más difícil de escribir y su forma real no se entiende de inmediato. Me pregunto si es una secuencia de comandos que se ejecutan en la terminal
En teoría, también me pregunto por qué no simplemente usar un Dockerfile
--grammar, y es muy buena para scripts bash que hacen todo tipo de tareas de clasificación de procesamiento de lenguaje natural limitando los logits de la salida del LLMFuera de eso, si necesito un LLM local uso ollama; cuando alquilo un servidor con GPU uso vllm; y si solo necesito el mejor modelo uso la API de OpenAI
Descargas llamafile, haces
chmod +xy lo ejecutas con./runAunque también es posible combinar Docker + llamafile. En https://github.com/ajbouh/cosmos hay una configuración de Dockerfile bastante buena
Me dan curiosidad las ventajas y desventajas de llamafile y ollama usados en el post original
Por eso puedes usar todo tipo de perillas de configuración con un esfuerzo mínimo. En particular, si descargas el llamafile “server”, se convierte en la forma más rápida de levantar un LLM local en una pestaña del navegador
https://huggingface.co/jartine/llava-v1.5-7B-GGUF/tree/main
llamafile también puede funcionar como chatbot de línea de comandos, pero para ese uso ollama ofrece una experiencia mucho más limpia y pulida
Quiero confirmar si entendí bien. Si uso llamafile desde un script de shell para, por ejemplo, renombrar archivos dentro de un directorio, ¿cada vez que se pase un nuevo nombre de archivo hay que abrir y cargar el ejecutable?
Entonces me pregunto si esa memoria se carga y descarga cada vez, o si hay algún caché genial que no conozco
La primera vez que ejecuté el ejemplo de subtitulado de imágenes en un M1 Pro tardó 13 segundos, la segunda 8 segundos, y las ejecuciones posteriores siguieron tardando un tiempo parecido
Si se procesan muchísimos archivos, realmente parecería necesario cargar los pesos una sola vez y mantenerlos mientras el proceso recorre el bucle
Aun así, sigue siendo muy útil e interesante
Mientras nada más reclame esa RAM, esas páginas permanecen cacheadas en memoria entre invocaciones de comandos
En una workstation de 128 GB, incluso usando varios modelos 7B en CPU, todos quedan en caché
En un modelo de 8 GB de VRAM, para completar unas pocas líneas es aproximadamente 6 segundos contra 2 segundos, y en una 3090 con 96 GB de RAM la inferencia corre toda en GPU
Si realmente haces trabajos por lotes, sin duda conviene mantener el modelo cargado entre completados
Por otro lado, tiene la desventaja de quedar atado al modelo cargado por el server. Si lo cargas cuando lo necesitas, puedes ir cambiando de modelo
Esto es importante para consultas multimodales con imágenes, porque otros modelos no entienden los tokens de imagen proyectados
En los pasos de instalación aparece el siguiente comando, y me pregunto si es seguro
Me pregunto si hay que hacer algo para ejecutar llamafile en Windows 10
Cuando ejecuto
llava-v1.5-7b-q4-server.llamafiledesde git bash, muere de inmediato con “Segmentation fault”, y en cmd no muestra ninguna salidaTambién probé descargar llamafile y el modelo por separado y ejecutar
llamafile.exe -m llava-v1.5-7b-Q4_K.gguf, pero el mismo problema persisteNo encontré problemas similares y, por lo que veo, no parece ser un tema del antivirus
cmd.exeo PowerShellPuedes pasar el flag
--straceo, si es posible,--ftracepara ver qué está pasando.llamafiledescargado a.exe.llamafilea.exe