Modelos y plataformas de IA
El marco de inferencia de Microsoft lleva los modelos de lenguaje grande de 1 bit a los dispositivos locales
El 17 de octubre de 2024, Microsoft anunció BitNet.cpp (MSFT ), un marco de inferencia diseñado para ejecutar modelos de lenguaje grande (LLM) cuantizados de 1 bit. BitNet.cpp es un progreso significativo en la inteligencia artificial generativa, que permite la implementación eficiente de LLM de 1 bit en CPUs estándar, sin requerir GPUs costosas. Este desarrollo democratiza el acceso a los LLM, haciéndolos disponibles en una amplia gama de dispositivos y brindando nuevas posibilidades en aplicaciones de inteligencia artificial en dispositivos.
Entendiendo los modelos de lenguaje grande de 1 bit
Los modelos de lenguaje grande (LLM) han requerido tradicionalmente recursos computacionales significativos debido a su uso de números de punto flotante de alta precisión (típicamente FP16 o BF16) para los pesos del modelo. Esta necesidad ha hecho que la implementación de LLM sea costosa y energéticamente intensiva.
En su núcleo, los LLM de 1 bit utilizan técnicas de cuantización extremas para representar los pesos del modelo utilizando solo tres valores posibles: -1, 0 y 1, de ahí el término “1,58 bits” (ya que requiere ligeramente más de un bit para codificar tres estados).
Sistema de peso ternario
El concepto
La cuantización de 1 bit en BitNet.cpp es un sistema de peso ternario. BitNet opera con solo tres valores posibles para cada parámetro:
- -1 (negativo)
- 0 (neutral)
- 1 (positivo)
Esto resulta en un requisito de almacenamiento de alrededor de 1,58 bits por parámetro, de ahí el nombre BitNet b1.58. Esta reducción drástica en el ancho de bits de los parámetros conduce a una reducción impresionante en el uso de memoria y la complejidad computacional, ya que la mayoría de las multiplicaciones de punto flotante se reemplazan con simples sumas y restas.
Fundamento matemático
La cuantización de 1 bit implica transformar los pesos y las activaciones en su representación ternaria a través de los siguientes pasos:
1. Cuantización de pesos
La cuantización de los pesos implica centralizarlos alrededor de la media (α), lo que da como resultado una representación ternaria. La transformación se expresa matemáticamente como:
Wf=Sign(W−α)
Donde:
- W es la matriz de pesos original.
- α es la media de los pesos.
- Sign(x) devuelve +1 si x > 0 y -1 de lo contrario.
2. Cuantización de activaciones
La cuantización de las activaciones garantiza que las entradas estén limitadas a un ancho de bits especificado:
x^e=Quant(x)=Clip(γx×Qb,−Qb+ϵ,Qb−ϵ)
Donde:
- Qb = 2(b−1)2^{(b-1)} es el nivel de cuantización máximo para el ancho de bits b.
- γ es el valor absoluto máximo de x (denotado como ∣∣x∣∣∞).
- ε es un número pequeño para prevenir desbordamientos durante los cálculos.
3. Operación BitLinear
La capa BitLinear reemplaza las multiplicaciones de matrices tradicionales con una operación simplificada:
y=Wf×x^e×(Qbβγ)
Donde:
- β es un factor de escala utilizado para minimizar errores de aproximación.
- γ escala las activaciones.
- Q_b es el factor de cuantización.
Esta transformación permite cálculos eficientes mientras se mantiene el rendimiento del modelo.
Implicaciones de rendimiento
Eficiencia de memoria
El sistema de peso ternario reduce significativamente los requisitos de memoria:
- LLM tradicionales: 16 bits por peso
- BitNet.cpp: 1,58 bits por peso
Esta reducción se traduce en un ahorro de memoria del 90% aproximadamente en comparación con los modelos de 16 bits tradicionales, lo que permite que los modelos más grandes se ajusten dentro de las mismas restricciones de hardware.
1. Velocidad de inferencia: más rápida en ambas CPUs
La velocidad de inferencia se representa como el número de tokens procesados por segundo. A continuación, se muestra un desglose de las observaciones:
- En Apple M2 Ultra: BitNet.cpp logra hasta 5,07 veces de velocidad para modelos más grandes (30B) en comparación con Llama.cpp, con una velocidad máxima de 593,43 tokens por segundo para un modelo de 125M, lo que es 1,37 veces más rápido. Para modelos más grandes como el 3,8B y el 7B, BitNet.cpp mantiene una velocidad superior a 84,77 tokens por segundo, demostrando su eficiencia en diferentes escalas.
- En Intel i7-13700H: BitNet.cpp logra mejoras de velocidad aún más dramáticas. En el tamaño de modelo de 7B, BitNet.cpp entrega una increíble velocidad 5,68 veces mayor en comparación con Llama.cpp. Para modelos más pequeños como el 125M, procesa 389,08 tokens por segundo, lo que es 2,37 veces más rápido que Llama.cpp.
2. Eficiencia energética: un cambio de juego para dispositivos periféricos
Los gráficos proporcionados también incluyen comparaciones de costos energéticos, lo que muestra una reducción significativa en el consumo de energía por token procesado:
- En Apple M2 Ultra: Los ahorros de energía de BitNet.cpp son sustanciales. Para el modelo de 700M, consume 55,4% menos energía por token en comparación con Llama.cpp, disminuyendo de 0,314 a 0,140. Esta tendencia continúa para modelos más grandes, con el modelo de 70B mostrando una reducción del 70,0% en el consumo de energía.
- En Intel i7-13700H: BitNet.cpp entrega 71,9% de ahorro de energía para el modelo de 700M, con un consumo que disminuye de 1,367 a 0,384. Aunque los datos de energía para el modelo de 70B en Llama.cpp no están disponibles, BitNet.cpp sigue siendo eficiente, con un consumo de energía de 17,33 para el modelo de 70B.
3. Superar el benchmark de velocidad de lectura humana
Una de las observaciones más interesantes de estos gráficos es la referencia a la velocidad de lectura humana, marcada en 5-7 tokens por segundo. Esta línea roja muestra que ambas implementaciones, especialmente BitNet.cpp, pueden superar cómodamente las velocidades de lectura humanas incluso para los modelos más grandes:
- En Apple M2 Ultra, BitNet.cpp supera la velocidad de lectura humana para todos los tamaños de modelo, con la velocidad más baja siendo 8,67 tokens por segundo para un modelo de 70B.
- En Intel i7-13700H, el modelo de 100B aún logra 1,70 tokens por segundo, casi tocando el rango inferior de la velocidad de lectura humana, mientras que todos los modelos más pequeños superan este benchmark.
Consideraciones de entrenamiento
Estimador de paso recto (STE)
Dado que la cuantización de 1 bit introduce funciones no diferenciables, el entrenamiento implica una técnica especializada conocida como Estimador de paso recto (STE). En este enfoque, los gradientes fluyen sin alteración a través de puntos no diferenciables. A continuación, se muestra una implementación simplificada en Python:
class StraightThroughEstimator(Function): @staticmethod def forward(ctx, input): return input.sign() @staticmethod def backward(ctx, grad_output): return grad_output
Entrenamiento de precisión mixta
Para mantener la estabilidad durante el entrenamiento, se emplea precisión mixta:
- Pesos y activaciones: Cuantizados a precisión de 1 bit.
- Gradientes y estados del optimizador: Almacenados en una precisión más alta.
- Pesos latentes: Mantenidos en alta precisión para facilitar actualizaciones precisas durante el entrenamiento.
Estrategia de tasa de aprendizaje grande
Un desafío único con los modelos de 1 bit es que las actualizaciones pequeñas pueden no afectar los pesos binarizados. Para mitigar esto, la tasa de aprendizaje se aumenta, lo que garantiza una convergencia más rápida y una mejor optimización en comparación con los enfoques tradicionales.
Cuantización y normalización de grupo
BitNet.cpp introduce cuantización y normalización de grupo para mejorar el paralelismo del modelo. En lugar de calcular parámetros para la matriz de pesos completa, BitNet divide los pesos y las activaciones en múltiples grupos (G).
Esta agrupación permite un procesamiento paralelo eficiente sin comunicación adicional entre grupos, lo que permite el entrenamiento y la inferencia de modelos a gran escala.
Notas de implementación y optimizaciones
Optimización de CPU
BitNet.cpp aprovecha varias optimizaciones de bajo nivel para lograr un rendimiento de CPU máximo:
- Operaciones vectorizadas: Utiliza instrucciones SIMD para realizar manipulaciones de bits de manera eficiente.
- Acceso a memoria amigable con la caché: Estructura los datos para minimizar los errores de caché.
- Procesamiento paralelo: Distribuye la carga de trabajo de manera efectiva a través de múltiples núcleos de CPU.
A continuación, se muestra un ejemplo de una función clave que implementa la cuantización y la inferencia en BitNet:
Modelos compatibles
La versión actual de BitNet.cpp admite los siguientes modelos de LLM de 1 bit disponibles en Hugging Face:
- bitnet_b1_58-large (0,7 mil millones de parámetros)
- bitnet_b1_58-3B (3,3 mil millones de parámetros)
- Llama3-8B-1.58-100B-tokens (8,0 mil millones de parámetros)
Estos modelos están disponibles públicamente para demostrar las capacidades de inferencia del marco. Aunque no fueron entrenados ni lanzados oficialmente por Microsoft, ilustran la versatilidad del marco.
Guía de instalación
Para comenzar con BitNet.cpp, siga los pasos a continuación:
Requisitos previos
- Python >= 3.9
- CMake >= 3.22
- Clang >= 18
- Conda (altamente recomendado)
Para los usuarios de Windows, se debe instalar Visual Studio con los siguientes componentes habilitados:
- Desarrollo de escritorio con C++
- Herramientas de C++-CMake para Windows
- Git para Windows
- Compilador de C++-Clang para Windows
- Soporte para MS-Build para el conjunto de herramientas de LLVM (Clang)
Para los usuarios de Debian/Ubuntu, hay un script de instalación automático disponible:
Pasos de instalación
- Clonar el repositorio:
- Instalar dependencias:
- Compilar y preparar el proyecto: Puede descargar un modelo directamente desde Hugging Face y convertirlo a un formato cuantizado:
Alternativamente, puede descargar y convertir el modelo manualmente:
Ejecutar la inferencia con BitNet.cpp
Para ejecutar la inferencia utilizando el marco, use el siguiente comando:
Explicación:
-mespecifica la ruta del archivo del modelo.-pdefine el texto de la promoción.-nestablece el número de tokens para predecir.-tempajusta la aleatoriedad de muestreo (temperatura) durante la inferencia.
Ejemplo de salida
Detalles técnicos de BitNet.cpp
Capa BitLinear
BitNet.cpp implementa una arquitectura de transformador modificada, sustituyendo las multiplicaciones de matrices estándar con operaciones BitLinear. Este enfoque centraliza los pesos en cero antes de la cuantización y los escala para reducir los errores de aproximación. La función de transformación clave se parece a esto:
# Función de binarización para pesos de 1 bit def binarize_weights(W): alpha = W.mean() W_binarized = np.sign(W - alpha) return W_binarized
La combinación de pesos centralizados y escalados garantiza que el error de cuantización permanece mínimo, preservando así el rendimiento.
Impacto en la industria
BitNet.cpp podría tener implicaciones de gran alcance para la implementación de LLM:
- Accesibilidad: Permite que los LLM se ejecuten en dispositivos estándar, democratizando el acceso a la inteligencia artificial potente.
- Eficiencia de costo: Reduce la necesidad de GPUs costosas, lo que reduce la barrera para la adopción.
- Eficiencia energética: Ahorra energía al aprovechar la inferencia basada en CPU.
- Innovación: Abre nuevas posibilidades para la inteligencia artificial en dispositivos, como la traducción de lenguaje en tiempo real, asistentes de voz y aplicaciones enfocadas en la privacidad sin dependencia de la nube.
Desafíos y direcciones futuras
Aunque los LLM de 1 bit tienen un gran potencial, varios desafíos persisten. Estos incluyen el desarrollo de modelos de 1 bit robustos para diversas tareas, la optimización del hardware para cálculos de 1 bit y el fomento de la adopción de este nuevo paradigma por parte de los desarrolladores. Además, explorar la cuantización de 1 bit para tareas de visión por computadora o audio representa una emocionante dirección futura.
Conclusión
El lanzamiento de BitNet.cpp por parte de Microsoft es un avance significativo. Al permitir la inferencia eficiente de 1 bit en CPUs estándar, BitNet.cpp crea la accesibilidad y la sostenibilidad de la inteligencia artificial. Este marco senta las bases para LLM más portátiles y rentables, empujando lo que es posible con la inteligencia artificial en dispositivos.














