7 个版本
新版本 0.3.2 | 2024 年 8 月 14 日 |
---|---|
0.3.1 | 2024 年 8 月 13 日 |
0.2.2 | 2024 年 6 月 30 日 |
0.2.1 | 2024 年 2 月 28 日 |
0.1.0 | 2023 年 12 月 16 日 |
#88 in 机器学习
每月 358 次下载
用于 rbert
310KB
3K SLoC
Kalosm
Kalosm 是 Rust 中预训练模型的简单接口。它使得与预训练的语言、音频和图像模型交互变得容易。
Kalosm 中有三个不同的包
kalosm::language
- 用于文本生成和嵌入模型的简单接口以及相关工具。它包括对搜索引擎、网站、RSS 源和搜索引擎的文本收集的支持。kalosm::audio
- 用于音频转录和相关工具的简单接口。它包括对麦克风输入、使用whisper
模型进行转录和语音活动检测的支持。kalosm::vision
- 用于图像生成和分割模型的简单接口和相关工具。它包括对wuerstchen
和segment-anything
模型的支持以及与 image crate 的集成。
有关 Kalosm 的完整指南可在 Kalosm 网站 上找到,示例代码位于 示例文件夹 中。
快速入门!
- 安装 rust
- 创建一个新的项目
cargo new next-gen-ai
cd ./next-gen-ai
- 将 Kalosm 添加为依赖项
cargo add kalosm --git https://github.com/floneum/floneum --features full
cargo add tokio --features full
- 将以下代码添加到您的
main.rs
文件中
use std::io::Write;
use kalosm::{*, language::*};
#[tokio::main]
async fn main() {
let mut llm = Llama::new().await.unwrap();
let prompt = "The following is a 300 word essay about Paris:";
print!("{}", prompt);
let mut stream = llm.stream_text(prompt).with_max_length(1000).await.unwrap();
stream.to_std_out().await.unwrap();
}
- 使用以下命令运行您的应用程序
cargo run --release
您可以使用 Kalosm 做什么?
您可以将 Kalosm 视为不同预训练模型之间或与周围世界的“管道”。Kalosm 使得构建使用预训练模型生成文本、音频和图像的应用程序变得简单。以下是您可以使用 Kalosm 构建的一些示例
本地文本生成
要开始使用 Kalosm 语言,最简单的方法是引入一个本地的大型语言模型,并使用它来生成文本。Kalosm 支持流式 API,允许您在不阻塞主线程的情况下实时生成文本
use kalosm::language::*;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut llm = Llama::phi_3().await.unwrap();
let prompt = "The following is a 300 word essay about why the capital of France is Paris:";
print!("{}", prompt);
let mut stream = llm.stream_text(prompt).with_max_length(1000).await.unwrap();
stream.to_std_out().await.unwrap();
Ok(())
}
结构化生成
自然语言生成很有趣,但文本作为通用数据格式的有趣方面更大。您可以使用类似 json 的格式将任何类型的数据编码成文本。Kalosm 允许您使用结构化生成与 LLMs 创建从自然语言输入派生的任意类型
use kalosm::language::*;
// First, derive an efficient parser for your structured data
#[derive(Parse, Clone, Debug)]
enum Class {
Thing,
Person,
Animal,
}
#[derive(Parse, Clone, Debug)]
struct Response {
classification: Class,
}
#[tokio::main]
async fn main() {
// Then set up a task with a prompt and constraints
let llm = Llama::new_chat().await.unwrap();
let task = Task::builder("You classify the user's message as about a person, animal or thing in a JSON format")
.with_constraints(Response::new_parser())
.build();
// Finally, run the task
let response = task.run("The Kalosm library lets you create structured data from natural language inputs", &llm).await.unwrap();
println!("{:?}", response);
}
云模型
Kalosm 还支持与云模型(如 GPT4)相同的流式 API
// You must set the environment variable OPENAI_API_KEY (https://platform.openai.com/account/api-keys) to run this example.
use kalosm::language::*;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut llm = Gpt4::default();
let prompt = "The following is a 300 word essay about why the capital of France is Paris:";
print!("{}", prompt);
let mut stream = llm.stream_text(prompt).with_max_length(300).await.unwrap();
stream.to_std_out().await.unwrap();
Ok(())
}
从 RSS、网站、本地文件、搜索结果等收集上下文
Kalosm 使您轻松地从各种来源收集文本数据。例如,您可以使用 Kalosm 从本地文档文件夹、RSS 流、网站或搜索引擎中收集文本
use kalosm::language::*;
use std::convert::TryFrom;
use std::path::PathBuf;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Read an RSS stream
let nyt = RssFeed::new(Url::parse("https://rss.nytimes.com/services/xml/rss/nyt/US.xml").unwrap());
// Read a local folder of documents
let mut documents = DocumentFolder::try_from(PathBuf::from("./documents")).unwrap();
// Read a website (either from the raw HTML or inside of a headless browser)
let page = Page::new(Url::parse("https://www.nytimes.com/live/2023/09/21/world/zelensky-russia-ukraine-news").unwrap(), BrowserMode::Static).unwrap();
let document = page.article().await.unwrap();
println!("Title: {}", document.title());
println!("Body: {}", document.body());
// Read pages from a search engine (You must have the SERPER_API_KEY environment variable set to run this example)
let query = "What is the capital of France?";
let api_key = std::env::var("SERPER_API_KEY").unwrap();
let search_query = SearchQuery::new(query, &api_key, 5);
let documents = search_query.into_documents().await.unwrap();
let mut text = String::new();
for document in documents {
for word in document.body().split(' ').take(300) {
text.push_str(word);
text.push(' ');
}
text.push('\n');
}
println!("{}", text);
Ok(())
}
基于嵌入的搜索
一旦您有了数据,Kalosm 就包括创建基于嵌入的搜索索引的工具。基于嵌入的搜索允许您找到与特定单词或短语语义上相似的文档,即使没有任何单词是完全匹配的
use kalosm::language::*;
use surrealdb::{engine::local::RocksDb, Surreal};
#[tokio::main]
async fn main() {
// Create database connection
let db = Surreal::new::<RocksDb>(std::env::temp_dir().join("temp.db")).await.unwrap();
// Select a specific namespace / database
db.use_ns("search").use_db("documents").await.unwrap();
// Create a table in the surreal database to store the embeddings
let document_table = db
.document_table_builder("documents")
.build::<Document>()
.await
.unwrap();
// Add documents to the database
document_table.add_context(DocumentFolder::new("./documents").unwrap()).await.unwrap();
loop {
// Get the user's question
let user_question = prompt_input("Query: ").unwrap();
let nearest_5 = document_table
.select_nearest(user_question, 5)
.await
.unwrap();
println!("{:?}", nearest_5);
}
}
资源增强生成
现代 LLMs 性能的关键部分是管理模型可访问的上下文。资源增强生成(或 RAG)通过根据搜索查询在提示中插入上下文来帮助您完成此操作。例如,您可以使用 Kalosm 创建一个聊天机器人,该机器人使用本地文档中的上下文来回答问题
use kalosm::language::*;
use surrealdb::{engine::local::RocksDb, Surreal};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let exists = std::path::Path::new("./db").exists();
// Create database connection
let db = Surreal::new::<RocksDb>("./db/temp.db").await?;
// Select a specific namespace / database
db.use_ns("test").use_db("test").await?;
// Create a table in the surreal database to store the embeddings
let document_table = db
.document_table_builder("documents")
.at("./db/embeddings.db")
.build::<Document>()
.await?;
// If the database is new, add documents to it
if !exists {
std::fs::create_dir_all("documents")?;
let context = [
"https://floneum.com/kalosm/docs",
"https://floneum.com/kalosm/docs/guides/retrieval_augmented_generation",
]
.iter()
.map(|url| Url::parse(url).unwrap());
document_table.add_context(context).await?;
}
// Create a llama chat model
let model = Llama::new_chat().await?;
let mut chat = Chat::builder(model).with_system_prompt("The assistant help answer questions based on the context given by the user. The model knows that the information the user gives it is always true.").build();
loop {
// Ask the user for a question
let user_question = prompt_input("\n> ")?;
// Search for relevant context in the document engine
let context = document_table
.select_nearest(&user_question, 1)
.await?
.into_iter()
.map(|document| {
format!(
"Title: {}\nBody: {}\n",
document.record.title(),
document.record.body()
)
})
.collect::<Vec<_>>()
.join("\n");
// Format a prompt with the question and context
let prompt = format!(
"{context}\n{user_question}"
);
// Display the prompt to the user for debugging purposes
println!("{}", prompt);
// And finally, respond to the user
let mut output_stream = chat.add_message(prompt);
print!("Bot: ");
output_stream.to_std_out().await?;
}
}
实时音频转录
Kalosm 使您轻松地构建有关您应用程序周围世界的上下文。
use kalosm::sound::*;
#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
// Create a new whisper model
let model = Whisper::new().await?;
// Stream audio from the microphone
let mic = MicInput::default();
let stream = mic.stream().unwrap();
// The audio into chunks based on voice activity and then transcribe those chunks
// The model will transcribe chunks of speech that are separated by silence
let mut text_stream = stream.transcribe(model);
// Finally, print the text to the console
text_stream.to_std_out().await.unwrap();
Ok(())
}
图像生成
除了语言、音频和嵌入模型之外,Kalosm 还支持图像生成。例如,您可以使用 Kalosm 从文本生成图像
use kalosm::vision::*;
#[tokio::main]
async fn main() {
let model = Wuerstchen::new().await.unwrap();
let settings = WuerstchenInferenceSettings::new(
"a cute cat with a hat in a room covered with fur with incredible detail",
);
if let Ok(mut images) = model.run(settings) {
while let Some(image) = images.next().await {
if let Some(buf) = image.generated_image() {
buf.save(&format!("{}.png",image.sample_num())).unwrap();
}
}
}
}
图像分割
Kalosm 还支持使用 segment-anything 模型进行图像分割
use kalosm::vision::*;
#[tokio::main]
async fn main() {
let model = SegmentAnything::builder().build().unwrap();
let image = image::open("examples/landscape.jpg").unwrap();
let images = model.segment_everything(image).unwrap();
for (i, img) in images.iter().enumerate() {
img.save(&format!("{}.png", i)).unwrap();
}
}
依赖项
~21–72MB
~1.5M SLoC