Packages
llama_cpp_ex
0.8.1
0.8.36
0.8.35
0.8.34
0.8.33
0.8.32
0.8.31
0.8.28
0.8.27
0.8.26
0.8.25
0.8.24
0.8.23
0.8.22
0.8.21
0.8.20
0.8.19
0.8.18
0.8.17
0.8.16
0.8.15
0.8.14
0.8.13
0.8.12
0.8.11
0.8.10
0.8.9
0.8.8
0.8.7
0.8.6
0.8.5
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.9
0.7.8
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.0
0.6.14
0.6.13
0.6.12
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.1
0.6.0
0.5.0
0.4.4
0.4.3
0.4.2
0.4.1
0.3.0
0.2.0
Elixir bindings for llama.cpp — run LLMs locally with Metal, CUDA, Vulkan, or CPU acceleration.
Current section
Files
Jump to
Current section
Files
lib/llama_cpp_ex/context.ex
defmodule LlamaCppEx.Context do
@moduledoc """
Inference context with KV cache.
"""
@enforce_keys [:ref, :model]
defstruct [:ref, :model]
@type t :: %__MODULE__{ref: reference(), model: LlamaCppEx.Model.t()}
@doc """
Creates a new inference context for the given model.
## Options
### Core
* `:n_ctx` - Context size (max tokens). Defaults to `2048`.
* `:n_batch` - Max tokens per decode batch. Defaults to `n_ctx`.
* `:n_ubatch` - Max tokens per micro-batch. Defaults to `512`.
* `:n_threads` - Number of threads for generation. Defaults to system CPU count.
* `:n_threads_batch` - Number of threads for prompt processing. Defaults to `:n_threads`.
* `:n_seq_max` - Max number of concurrent sequences. Defaults to `1`.
* `:embeddings` - Enable embedding extraction. Defaults to `false`.
* `:pooling_type` - Pooling type for embeddings: `:unspecified`, `:none`, `:mean`,
`:cls`, `:last`, `:rank`. Defaults to `:unspecified`.
### KV Cache Quantization
* `:type_k` - Data type for K cache. Reduces memory at the cost of precision.
Values: `:f16` (default), `:f32`, `:q8_0`, `:q4_0`, `:q4_1`, `:q5_0`, `:q5_1`, `:bf16`.
* `:type_v` - Data type for V cache. Same values as `:type_k`. Defaults to `:f16`.
### Flash Attention & GPU Offload
* `:flash_attn` - Flash Attention mode: `:auto` (default), `:enabled`, `:disabled`.
* `:offload_kqv` - Offload KQV ops and KV cache to GPU. Defaults to `true`.
* `:op_offload` - Offload host tensor operations to device. Defaults to `true`.
### RoPE Scaling (Context Extension)
* `:rope_scaling_type` - RoPE scaling mode: `:unspecified` (default), `:none`,
`:linear`, `:yarn`, `:longrope`.
* `:rope_freq_base` - RoPE base frequency. `0.0` uses model default.
* `:rope_freq_scale` - RoPE frequency scale. `0.0` uses model default.
* `:yarn_ext_factor` - YaRN extrapolation mix factor. `-1.0` to disable.
* `:yarn_attn_factor` - YaRN magnitude scaling. `-1.0` to disable.
* `:yarn_beta_fast` - YaRN low correction dimension. `-1.0` to disable.
* `:yarn_beta_slow` - YaRN high correction dimension. `-1.0` to disable.
* `:yarn_orig_ctx` - YaRN original context length. `0` to disable.
### Misc
* `:attention_type` - Attention type: `:unspecified` (default), `:causal`, `:non_causal`.
Use `:non_causal` for embedding models.
* `:no_perf` - Disable performance timing. Defaults to `true`.
* `:swa_full` - Use full-size sliding window attention cache. Defaults to `true`.
"""
@spec create(LlamaCppEx.Model.t(), keyword()) :: {:ok, t()} | {:error, String.t()}
def create(%LlamaCppEx.Model{ref: model_ref} = model, opts \\ []) do
# Core
n_threads = Keyword.get(opts, :n_threads, System.schedulers_online())
n_ctx = Keyword.get(opts, :n_ctx, 2048)
n_batch = Keyword.get(opts, :n_batch, n_ctx)
n_ubatch = Keyword.get(opts, :n_ubatch, 512)
n_threads_batch = Keyword.get(opts, :n_threads_batch, n_threads)
embeddings = Keyword.get(opts, :embeddings, false)
pooling_type = Keyword.get(opts, :pooling_type, :unspecified) |> pooling_type_to_int()
n_seq_max = Keyword.get(opts, :n_seq_max, 1)
# KV cache quantization
type_k = Keyword.get(opts, :type_k, :f16) |> ggml_type_to_int()
type_v = Keyword.get(opts, :type_v, :f16) |> ggml_type_to_int()
# Flash attention & GPU offload
flash_attn = Keyword.get(opts, :flash_attn, :auto) |> flash_attn_to_int()
offload_kqv = Keyword.get(opts, :offload_kqv, true)
op_offload = Keyword.get(opts, :op_offload, true)
# RoPE scaling
rope_scaling_type =
Keyword.get(opts, :rope_scaling_type, :unspecified) |> rope_scaling_to_int()
rope_freq_base = Keyword.get(opts, :rope_freq_base, 0.0) / 1
rope_freq_scale = Keyword.get(opts, :rope_freq_scale, 0.0) / 1
yarn_ext_factor = Keyword.get(opts, :yarn_ext_factor, -1.0) / 1
yarn_attn_factor = Keyword.get(opts, :yarn_attn_factor, -1.0) / 1
yarn_beta_fast = Keyword.get(opts, :yarn_beta_fast, -1.0) / 1
yarn_beta_slow = Keyword.get(opts, :yarn_beta_slow, -1.0) / 1
yarn_orig_ctx = Keyword.get(opts, :yarn_orig_ctx, 0)
# Misc
attention_type = Keyword.get(opts, :attention_type, :unspecified) |> attention_type_to_int()
no_perf = Keyword.get(opts, :no_perf, true)
swa_full = Keyword.get(opts, :swa_full, true)
case LlamaCppEx.NIF.context_create(
model_ref,
n_ctx,
n_batch,
n_ubatch,
n_threads,
n_threads_batch,
embeddings,
pooling_type,
n_seq_max,
type_k,
type_v,
flash_attn,
offload_kqv,
op_offload,
rope_scaling_type,
rope_freq_base,
rope_freq_scale,
yarn_ext_factor,
yarn_attn_factor,
yarn_beta_fast,
yarn_beta_slow,
yarn_orig_ctx,
attention_type,
no_perf,
swa_full
) do
{:ok, ref} -> {:ok, %__MODULE__{ref: ref, model: model}}
{:error, _} = error -> error
end
end
@doc "Returns the context size."
@spec n_ctx(t()) :: integer()
def n_ctx(%__MODULE__{ref: ref}), do: LlamaCppEx.NIF.context_n_ctx(ref)
@doc "Returns the max number of sequences."
@spec n_seq_max(t()) :: integer()
def n_seq_max(%__MODULE__{ref: ref}), do: LlamaCppEx.NIF.context_n_seq_max(ref)
@doc "Clears the KV cache."
@spec clear(t()) :: :ok
def clear(%__MODULE__{ref: ref}), do: LlamaCppEx.NIF.memory_clear(ref)
@doc """
Decodes a list of tokens through the model.
"""
@spec decode(t(), [integer()]) :: :ok | {:error, String.t()}
def decode(%__MODULE__{ref: ref}, tokens) when is_list(tokens) do
LlamaCppEx.NIF.decode(ref, tokens)
end
@doc """
Runs the generation loop: decodes prompt tokens and generates up to `max_tokens` new tokens.
Returns the generated text (not including the prompt).
## Options
* `:max_tokens` - Maximum tokens to generate. Defaults to `256`.
"""
@spec generate(t(), LlamaCppEx.Sampler.t(), [integer()], keyword()) ::
{:ok, String.t()} | {:error, String.t()}
def generate(
%__MODULE__{ref: ctx_ref},
%LlamaCppEx.Sampler{ref: sampler_ref},
tokens,
opts \\ []
) do
max_tokens = Keyword.get(opts, :max_tokens, 256)
LlamaCppEx.NIF.generate(ctx_ref, sampler_ref, tokens, max_tokens)
end
# --- Enum mappings ---
defp pooling_type_to_int(:unspecified), do: -1
defp pooling_type_to_int(:none), do: 0
defp pooling_type_to_int(:mean), do: 1
defp pooling_type_to_int(:cls), do: 2
defp pooling_type_to_int(:last), do: 3
defp pooling_type_to_int(:rank), do: 4
defp pooling_type_to_int(n) when is_integer(n), do: n
defp ggml_type_to_int(:f32), do: 0
defp ggml_type_to_int(:f16), do: 1
defp ggml_type_to_int(:q4_0), do: 2
defp ggml_type_to_int(:q4_1), do: 3
defp ggml_type_to_int(:q5_0), do: 6
defp ggml_type_to_int(:q5_1), do: 7
defp ggml_type_to_int(:q8_0), do: 8
defp ggml_type_to_int(:bf16), do: 30
defp ggml_type_to_int(n) when is_integer(n), do: n
defp flash_attn_to_int(:auto), do: -1
defp flash_attn_to_int(:disabled), do: 0
defp flash_attn_to_int(:enabled), do: 1
defp flash_attn_to_int(n) when is_integer(n), do: n
defp rope_scaling_to_int(:unspecified), do: -1
defp rope_scaling_to_int(:none), do: 0
defp rope_scaling_to_int(:linear), do: 1
defp rope_scaling_to_int(:yarn), do: 2
defp rope_scaling_to_int(:longrope), do: 3
defp rope_scaling_to_int(n) when is_integer(n), do: n
defp attention_type_to_int(:unspecified), do: -1
defp attention_type_to_int(:causal), do: 0
defp attention_type_to_int(:non_causal), do: 1
defp attention_type_to_int(n) when is_integer(n), do: n
end