viva_tensor/nf4

NF4 (NormalFloat4) Quantization - QLoRA Style

DESCOBERTA VIA HUGGINGCHAT + PESQUISA: NF4 usa 16 níveis derivados dos quantis da distribuição normal Isso é ÓTIMO para pesos de NNs que seguem distribuição gaussiana!

Referências:

Vantagens sobre Q4 uniforme:

Types

Double Quantization: quantiza os próprios scales Reduz overhead de metadados de 0.5 bits/param para 0.127 bits/param

pub type DoubleQuantNF4 {
  DoubleQuantNF4(
    blocks: List(NF4Block),
    quantized_scales: List(Int),
    scales_scale: Float,
    shape: List(Int),
    num_elements: Int,
    memory_bytes: Int,
  )
}

Constructors

  • DoubleQuantNF4(
      blocks: List(NF4Block),
      quantized_scales: List(Int),
      scales_scale: Float,
      shape: List(Int),
      num_elements: Int,
      memory_bytes: Int,
    )

    Arguments

    blocks

    Blocos com índices NF4

    quantized_scales

    Scales quantizados (INT8)

    scales_scale

    Scale global para os scales

    shape

    Shape original

    num_elements

    Número de elementos

    memory_bytes

    Memória em bytes

Bloco NF4 quantizado (tipicamente 64 valores)

pub type NF4Block {
  NF4Block(indices: List(Int), abs_max: Float, block_size: Int)
}

Constructors

  • NF4Block(indices: List(Int), abs_max: Float, block_size: Int)

    Arguments

    indices

    Índices 4-bit (0-15) para cada valor

    abs_max

    Escala do bloco (abs_max original)

    block_size

    Tamanho do bloco

Configuração de quantização

pub type NF4Config {
  NF4Config(block_size: Int, double_quant: Bool)
}

Constructors

  • NF4Config(block_size: Int, double_quant: Bool)

    Arguments

    block_size

    Tamanho do bloco (64 é padrão QLoRA)

    double_quant

    Usar Double Quantization (quantiza os scales também)

Estatísticas de quantização

pub type NF4Stats {
  NF4Stats(
    original_bytes: Int,
    compressed_bytes: Int,
    compression_ratio: Float,
    mean_error: Float,
    max_error: Float,
    num_blocks: Int,
  )
}

Constructors

  • NF4Stats(
      original_bytes: Int,
      compressed_bytes: Int,
      compression_ratio: Float,
      mean_error: Float,
      max_error: Float,
      num_blocks: Int,
    )

Tensor completo quantizado em NF4

pub type NF4Tensor {
  NF4Tensor(
    blocks: List(NF4Block),
    shape: List(Int),
    num_elements: Int,
    memory_bytes: Int,
    compression_ratio: Float,
  )
}

Constructors

  • NF4Tensor(
      blocks: List(NF4Block),
      shape: List(Int),
      num_elements: Int,
      memory_bytes: Int,
      compression_ratio: Float,
    )

    Arguments

    blocks

    Lista de blocos quantizados

    shape

    Shape original

    num_elements

    Número de elementos

    memory_bytes

    Memória em bytes

    compression_ratio

    Taxa de compressão

Values

pub fn benchmark_nf4() -> Nil
pub fn compute_stats(
  original: tensor.Tensor,
  nf4: NF4Tensor,
) -> NF4Stats

Calcula estatísticas de erro

pub fn default_config() -> NF4Config

Configuração padrão QLoRA

pub fn dequantize(nf4: NF4Tensor) -> tensor.Tensor

Dequantiza tensor NF4 de volta para FP32

pub fn double_quantize(
  t: tensor.Tensor,
  config: NF4Config,
) -> DoubleQuantNF4

Aplica Double Quantization

pub fn main() -> Nil
pub fn nf4_levels() -> List(Float)

Os 16 níveis NF4 são os quantis de N(0,1) normalizados para [-1, 1] Esses valores são hardcoded em bitsandbytes e usados em QLoRA

pub fn quantize(t: tensor.Tensor, config: NF4Config) -> NF4Tensor

Quantiza tensor para NF4

Search Document