Rust的Llama.cpp绑定库llama-cpp-sys-2的使用:高效集成C++机器学习框架Llama到Rust生态

Rust的Llama.cpp绑定库llama-cpp-sys-2的使用

llama-cpp-sysllama.cpp 的原始绑定库,支持CUDA。如需安全API,请参考其他相关库。

安装

在项目目录中运行以下Cargo命令:

cargo add llama-cpp-sys-2

或者在 Cargo.toml 中添加以下行:

llama-cpp-sys-2 = "0.1.114"

示例代码

以下是使用 llama-cpp-sys-2 的完整示例:

use llama_cpp_sys_2::{llama_context, llama_context_params, llama_init_from_file};

fn main() {
    // 初始化llama上下文参数
    let params = llama_context_params {
        n_ctx: 512,  // 上下文长度
        n_parts: -1,  // 加载所有部分
        seed: 0,      // 随机种子
        f16_kv: false, // 不使用半精度KV缓存
        logits_all: false,
        vocab_only: false,
        use_mlock: false,
        embedding: false,
        ..Default::default()
    };

    // 加载模型文件
    let model_path = "path/to/your/model.bin";
    let ctx = unsafe { llama_init_from_file(model_path.as_ptr() as *const i8, params) };

    if ctx.is_null() {
        eprintln!("Failed to initialize llama context");
        return;
    }

    // 在这里添加你的推理代码...

    // 清理资源
    unsafe { llama_free(ctx) };
}

完整示例代码

以下是一个更完整的示例,包含模型推理部分:

use llama_cpp_sys_2::{
    llama_context, 
    llama_context_params, 
    llama_init_from_file,
    llama_token,
    llama_token_to_str,
    llama_tokenize,
    llama_eval,
    llama_free,
    llama_get_logits
};

fn main() {
    // 初始化参数
    let params = llama_context_params {
        n_ctx: 512,
        n_parts: -1,
        seed: 0,
        f16_kv: false,
        logits_all: false,
        vocab_only: false,
        use_mlock: false,
        embedding: false,
        ..Default::default()
    };

    // 加载模型
    let model_path = "path/to/your/model.bin";
    let ctx = unsafe { llama_init_from_file(model_path.as_ptr() as *const i8, params) };

    if ctx.is_null() {
        eprintln!("Failed to load model");
        return;
    }

    // 准备输入文本
    let text = "Rust is a";
    let mut tokens: Vec<llama_token> = vec![0; text.len() + 1];
    
    // 分词
    let n_tokens = unsafe {
        llama_tokenize(
            ctx,
            text.as_ptr() as *const i8,
            tokens.as_mut_ptr(),
            tokens.len() as i32,
            0
        )
    };
    tokens.truncate(n_tokens as usize);

    // 评估模型
    let res = unsafe { llama_eval(ctx, tokens.as_ptr(), tokens.len() as i32, 0, 1) };
    if res != 0 {
        eprintln!("Failed to evaluate model");
        unsafe { llama_free(ctx) };
        return;
    }

    // 获取预测结果
    let logits = unsafe { llama_get_logits(ctx) };
    // 这里可以添加处理logits的代码...

    // 示例:获取token对应的字符串
    for token in tokens {
        let c_str = unsafe { llama_token_to_str(ctx, token) };
        let str_slice = unsafe { std::ffi::CStr::from_ptr(c_str) }.to_str().unwrap();
        println!("Token {}: {}", token, str_slice);
    }

    // 释放资源
    unsafe { llama_free(ctx) };
}

许可证

本项目采用MIT或Apache-2.0许可证。


1 回复

Rust的Llama.cpp绑定库llama-cpp-sys-2使用指南

llama-cpp-sys-2是一个Rust绑定库,用于将C++机器学习框架Llama集成到Rust生态系统中。它提供了对Llama.cpp的高效访问,让Rust开发者能够利用Llama的强大功能。

主要特性

  • 高性能的Rust与C++互操作
  • 完整的Llama.cpp功能绑定
  • 内存安全接口
  • 支持多种硬件加速(CPU/GPU)

安装方法

在Cargo.toml中添加依赖:

[dependencies]
llama-cpp-sys-2 = "0.2"

基本使用方法

1. 初始化模型

use llama_cpp_sys_2::{Model, ModelParams};

fn main() {
    let params = ModelParams::default();
    let model = Model::new_from_file("path/to/model.bin", &params).unwrap();
    
    // 使用模型...
}

2. 文本生成示例

use llama_cpp_sys_2::{Model, ModelParams, GenerateParams};

fn generate_text() {
    let model_params = ModelParams::default();
    let model = Model::new_from_file("path/to/model.bin", &model_params).unwrap();
    
    let generate_params = GenerateParams {
        prompt: "Rust is".to_string(),
        max_tokens: 100,
        temperature: 0.7,
        ..Default::default()
    };
    
    let result = model.generate(&generate_params).unwrap();
    println!("Generated text: {}", result);
}

3. 高级用法 - 带回调的流式生成

use llama_cpp_sys_2::{Model, ModelParams, GenerateParams, GenerateCallback};

struct MyCallback;

impl GenerateCallback for MyCallback {
    fn on_token(&mut self, token: String) -> bool {
        print!("{}", token);
        true // 返回false可中断生成
    }
}

fn streaming_generation() {
    let model = Model::new_from_file("path/to/model.bin", &ModelParams::default()).unwrap();
    
    let generate_params = GenerateParams {
        prompt: "Explain Rust's ownership system:".to_string(),
        max_tokens: 500,
        ..Default::default()
    };
    
    let mut callback = MyCallback;
    model.generate_with_callback(&generate_params, &mut callback).unwrap();
}

性能优化技巧

  1. 批处理请求:同时处理多个提示可以提高吞吐量
  2. 调整线程数:根据CPU核心数设置合适的线程数
  3. 使用GPU加速:如果硬件支持,启用GPU加速
let mut params = ModelParams::default();
params.n_threads = 8; // 设置8个线程
params.use_gpu = true; // 启用GPU加速

错误处理

所有主要函数都返回Result类型,建议使用Rust的错误处理机制:

match Model::new_from_file("path/to/model.bin", &ModelParams::default()) {
    Ok(model) => {
        // 使用模型
    },
    Err(e) => {
        eprintln!("Failed to load model: {}", e);
    }
}

注意事项

  1. 确保Llama.cpp的模型文件与绑定版本兼容
  2. 大型模型需要足够的内存
  3. 首次运行时可能需要下载模型文件

完整示例demo

以下是一个完整的示例,展示了如何使用llama-cpp-sys-2进行文本生成:

use llama_cpp_sys_2::{Model, ModelParams, GenerateParams, GenerateCallback};

// 自定义回调结构体,用于流式生成
struct GenerationCallback;

impl GenerateCallback for GenerationCallback {
    fn on_token(&mut self, token: String) -> bool {
        print!("{}", token);
        std::io::stdout().flush().unwrap();
        true // 返回true继续生成,返回false停止生成
    }
}

fn main() {
    // 1. 初始化模型
    let mut model_params = ModelParams::default();
    model_params.n_threads = 4; // 设置4个线程
    model_params.use_gpu = true; // 启用GPU加速
    
    let model = match Model::new_from_file("path/to/model.bin", &model_params) {
        Ok(m) => m,
        Err(e) => {
            eprintln!("模型加载失败: {}", e);
            return;
        }
    };

    // 2. 简单文本生成
    println!("=== 简单文本生成 ===");
    let simple_params = GenerateParams {
        prompt: "Rust语言的主要特点是".to_string(),
        max_tokens: 50,
        temperature: 0.7,
        ..Default::default()
    };
    
    let result = model.generate(&simple_params).unwrap();
    println!("\n生成结果: {}", result);

    // 3. 流式生成
    println!("\n=== 流式生成 ===");
    let stream_params = GenerateParams {
        prompt: "请解释Rust的所有权系统:".to_string(),
        max_tokens: 200,
        temperature: 0.5,
        ..Default::default()
    };
    
    let mut callback = GenerationCallback;
    println!("开始流式生成...");
    model.generate_with_callback(&stream_params, &mut callback).unwrap();
    println!("\n流式生成完成");
}

这个示例展示了:

  1. 模型初始化和配置
  2. 简单的文本生成
  3. 流式生成(带回调)
  4. 错误处理
  5. 性能优化配置(线程数和GPU加速)

要运行此示例,您需要:

  1. 安装Rust工具链
  2. 在Cargo.toml中添加llama-cpp-sys-2依赖
  3. 准备兼容的Llama.cpp模型文件
回到顶部