Skip to main content

Overview

The libllama C API provides a complete interface for loading and running large language models in C/C++ applications. The API is designed around four core concepts:
  • Model: Loaded from GGUF files, contains model weights and architecture
  • Context: Runtime state for inference, manages KV cache and computation
  • Batch: Input data structure for encoding/decoding tokens
  • Sampler: Token selection strategies for text generation

Initialization

Before using the library, initialize the backend:
void llama_backend_init(void);
void llama_backend_free(void);
Call llama_backend_init() once at program startup. For cleanup, call llama_backend_free() at program exit.

NUMA Support (Optional)

void llama_numa_init(enum ggml_numa_strategy numa);
Optionally configure NUMA (Non-Uniform Memory Access) optimizations for multi-socket systems.

Basic Usage Pattern

The typical workflow for using libllama follows this pattern:
// 1. Initialize backend
llama_backend_init();

// 2. Load model
llama_model_params model_params = llama_model_default_params();
model_params.n_gpu_layers = 32;
llama_model * model = llama_model_load_from_file("model.gguf", model_params);

// 3. Create context
llama_context_params ctx_params = llama_context_default_params();
ctx_params.n_ctx = 2048;
llama_context * ctx = llama_init_from_model(model, ctx_params);

// 4. Initialize sampler
llama_sampler * sampler = llama_sampler_chain_init(
    llama_sampler_chain_default_params()
);
llama_sampler_chain_add(sampler, llama_sampler_init_greedy());

// 5. Tokenize input
const llama_vocab * vocab = llama_model_get_vocab(model);
std::vector<llama_token> tokens(256);
int n_tokens = llama_tokenize(
    vocab, 
    "Hello, world!", 13,
    tokens.data(), tokens.size(),
    true,  // add_special
    false  // parse_special
);

// 6. Create batch and decode
llama_batch batch = llama_batch_get_one(tokens.data(), n_tokens);
llama_decode(ctx, batch);

// 7. Sample next token
llama_token new_token = llama_sampler_sample(sampler, ctx, -1);

// 8. Cleanup
llama_sampler_free(sampler);
llama_free(ctx);
llama_model_free(model);
llama_backend_free();

Simple Example

Here’s a complete minimal example based on examples/simple/simple.cpp:
#include "llama.h"
#include <cstdio>
#include <string>
#include <vector>

int main(int argc, char ** argv) {
    // Initialize backend
    ggml_backend_load_all();
    
    // Load model
    llama_model_params model_params = llama_model_default_params();
    model_params.n_gpu_layers = 99;
    
    llama_model * model = llama_model_load_from_file("model.gguf", model_params);
    if (model == NULL) {
        fprintf(stderr, "error: unable to load model\n");
        return 1;
    }
    
    // Get vocabulary for tokenization
    const llama_vocab * vocab = llama_model_get_vocab(model);
    
    // Tokenize prompt
    std::string prompt = "Hello my name is";
    const int n_prompt = -llama_tokenize(vocab, prompt.c_str(), prompt.size(), 
                                          NULL, 0, true, true);
    
    std::vector<llama_token> prompt_tokens(n_prompt);
    llama_tokenize(vocab, prompt.c_str(), prompt.size(), 
                   prompt_tokens.data(), prompt_tokens.size(), true, true);
    
    // Create context
    llama_context_params ctx_params = llama_context_default_params();
    ctx_params.n_ctx = n_prompt + 32;  // prompt + n_predict
    ctx_params.n_batch = n_prompt;
    ctx_params.no_perf = false;
    
    llama_context * ctx = llama_init_from_model(model, ctx_params);
    if (ctx == NULL) {
        fprintf(stderr, "error: failed to create context\n");
        return 1;
    }
    
    // Initialize sampler
    auto sparams = llama_sampler_chain_default_params();
    sparams.no_perf = false;
    llama_sampler * smpl = llama_sampler_chain_init(sparams);
    llama_sampler_chain_add(smpl, llama_sampler_init_greedy());
    
    // Prepare batch
    llama_batch batch = llama_batch_get_one(prompt_tokens.data(), 
                                            prompt_tokens.size());
    
    // Generation loop
    for (int n_pos = 0; n_pos + batch.n_tokens < ctx_params.n_ctx; ) {
        if (llama_decode(ctx, batch)) {
            fprintf(stderr, "failed to decode\n");
            return 1;
        }
        
        n_pos += batch.n_tokens;
        
        // Sample next token
        llama_token new_token_id = llama_sampler_sample(smpl, ctx, -1);
        
        if (llama_vocab_is_eog(vocab, new_token_id)) {
            break;
        }
        
        // Print token
        char buf[128];
        int n = llama_token_to_piece(vocab, new_token_id, buf, sizeof(buf), 0, true);
        printf("%.*s", n, buf);
        
        // Prepare next batch
        batch = llama_batch_get_one(&new_token_id, 1);
    }
    
    // Cleanup
    llama_sampler_free(smpl);
    llama_free(ctx);
    llama_model_free(model);
    
    return 0;
}

Core Data Types

Type Definitions

typedef int32_t llama_pos;      // Position in sequence
typedef int32_t llama_token;    // Token ID
typedef int32_t llama_seq_id;   // Sequence ID

typedef struct llama_memory_i * llama_memory_t;

Core Structures

struct llama_model;     // Opaque model handle
struct llama_context;   // Opaque context handle
struct llama_vocab;     // Opaque vocabulary handle
struct llama_sampler;   // Opaque sampler handle

Default Parameters

Get default parameter structures:
struct llama_model_params llama_model_default_params(void);
struct llama_context_params llama_context_default_params(void);
struct llama_sampler_chain_params llama_sampler_chain_default_params(void);
struct llama_model_quantize_params llama_model_quantize_default_params(void);

Query Functions

Retrieve model and context information:
// Model properties
int32_t llama_model_n_ctx_train(const struct llama_model * model);
int32_t llama_model_n_embd(const struct llama_model * model);
int32_t llama_model_n_layer(const struct llama_model * model);
int32_t llama_model_n_head(const struct llama_model * model);
uint64_t llama_model_n_params(const struct llama_model * model);
uint64_t llama_model_size(const struct llama_model * model);

// Model capabilities
bool llama_model_has_encoder(const struct llama_model * model);
bool llama_model_has_decoder(const struct llama_model * model);
bool llama_model_is_recurrent(const struct llama_model * model);

System Information

const char * llama_print_system_info(void);

bool llama_supports_mmap(void);
bool llama_supports_mlock(void);
bool llama_supports_gpu_offload(void);
bool llama_supports_rpc(void);

size_t llama_max_devices(void);

Performance Monitoring

struct llama_perf_context_data {
    double t_start_ms;   // Absolute start time
    double t_load_ms;    // Model loading time
    double t_p_eval_ms;  // Prompt processing time
    double t_eval_ms;    // Token generation time
    
    int32_t n_p_eval;    // Number of prompt tokens
    int32_t n_eval;      // Number of generated tokens
    int32_t n_reused;    // Number of graph reuses
};

struct llama_perf_context_data llama_perf_context(const struct llama_context * ctx);
void llama_perf_context_print(const struct llama_context * ctx);
void llama_perf_context_reset(struct llama_context * ctx);

Constants

#define LLAMA_DEFAULT_SEED 0xFFFFFFFF
#define LLAMA_TOKEN_NULL -1

#define LLAMA_FILE_MAGIC_GGLA 0x67676c61u  // 'ggla'
#define LLAMA_FILE_MAGIC_GGSN 0x6767736eu  // 'ggsn'
#define LLAMA_FILE_MAGIC_GGSQ 0x67677371u  // 'ggsq'

Thread Safety

The tokenization API (llama_tokenize, llama_detokenize, llama_token_to_piece) is thread-safe. Other APIs require external synchronization.

Error Handling

Most functions return NULL, -1, 0, or negative values to indicate errors. Always check return values:
llama_model * model = llama_model_load_from_file(path, params);
if (model == NULL) {
    // Handle error: model file not found or invalid
}

llama_context * ctx = llama_init_from_model(model, ctx_params);
if (ctx == NULL) {
    // Handle error: context creation failed
}

int result = llama_decode(ctx, batch);
if (result != 0) {
    // Handle error: decoding failed
    // result == 1: no KV slot available
    // result == 2: aborted
    // result < 0: fatal error
}

Next Steps

Model Loading

Learn how to load models and configure parameters

Inference

Understand batching, decoding, and KV cache management

Sampling

Explore token sampling strategies and configuration