Version v2.0
You're viewing docs for v2.0. If you are cloning the repository, make sure to check out this release: git checkout v2.0
Quickstart¶
Install Cactus and run your first on-device AI completion.
Installation¶
Platform Integration¶
- Add the bridge files from this folder to your React Native app
- Add the raw bindings they depend on:
bindings/kotlin/(Android),bindings/swift/(Apple) - Register the Android package in
MainApplication.kt:
Platform Integration¶
- Copy
android/libcactus_engine.soto your app'sjniLibs/arm64-v8a/ - Add
apple/cactus-ios.xcframeworkto your Xcode project (iOS) - Add
apple/cactus-macos.xcframeworkto your Xcode project (macOS) - Copy
cactus.dartinto your Dart source tree - Add
ffitopubspec.yaml
Platform Integration¶
- Copy
android/libcactus_engine.sotoapp/src/main/jniLibs/arm64-v8a/ - Copy
Cactus.ktandCactusCallbacks.ktto your Kotlin source tree
Platform Integration¶
XCFramework: drag apple/cactus-ios.xcframework (or apple/cactus-macos.xcframework) into Xcode (Embed & Sign). The framework bundles cactus_engine.h, so import cactus works directly.
Static library: link apple/libcactus_engine-device.a (or apple/libcactus_engine-simulator.a), copy bindings/swift/module.modulemap into your project, and add cactus-engine/ to Header Search Paths so the module map can find cactus_engine.h.
Homebrew (macOS):
From Source (macOS):
brew install cmake
git clone https://github.com/cactus-compute/cactus && cd cactus && source ./setup && cactus build --python
From Source (Linux):
Include the Cactus header in your project:
See the Cactus repository for CMake build instructions.
Your First Completion¶
import 'cactus.dart';
import 'package:ffi/ffi.dart';
final modelPath = '/path/to/model'.toNativeUtf8();
final model = cactusInit(modelPath, nullptr, false);
calloc.free(modelPath);
const messagesJson = '[{"role":"user","content":"Hello"}]';
final msgs = messagesJson.toNativeUtf8();
final buf = calloc<Int8>(65536);
cactusComplete(model, msgs, buf.cast(), 65536, nullptr, nullptr, nullptr, nullptr, nullptr, 0);
final response = buf.cast<Utf8>().toDartString();
calloc.free(msgs);
calloc.free(buf);
cactusDestroy(model);
from cactus import ensure_model
from cactus import cactus_init, cactus_complete, cactus_destroy
import json
# Downloads the pre-built bundle from HuggingFace if not already present
bundle = ensure_model("LiquidAI/LFM2-VL-450M")
model = cactus_init(str(bundle), None, False)
messages = json.dumps([{"role": "user", "content": "What is 2+2?"}])
result = cactus_complete(model, messages, None, None, None)
print(result["response"])
cactus_destroy(model)
use std::ffi::CString;
use std::os::raw::c_char;
mod cactus;
fn main() {
unsafe {
let model_path = CString::new("path/to/weight/folder").unwrap();
let model = cactus::cactus_init(model_path.as_ptr(), std::ptr::null(), false);
let messages = CString::new(
r#"[{"role": "user", "content": "What is the capital of France?"}]"#
).unwrap();
let mut response = vec![0u8; 4096];
cactus::cactus_complete(
model, messages.as_ptr(),
response.as_mut_ptr() as *mut c_char, response.len(),
std::ptr::null(), std::ptr::null(),
None, std::ptr::null_mut(),
std::ptr::null(), 0,
);
println!("{}", String::from_utf8_lossy(&response));
cactus::cactus_destroy(model);
}
}
#include <cactus_engine.h>
cactus_model_t model = cactus_init(
"path/to/weight/folder",
"path/to/rag/documents",
false
);
const char* messages = R"([
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "What is the capital of France?"}
])";
char response[4096];
int result = cactus_complete(
model, messages, response, sizeof(response),
nullptr, nullptr, nullptr, nullptr,
nullptr, 0
);
Next Steps¶
- Engine API -- Full inference API reference
- Graph API -- Zero-copy computation graph for custom models
- Fine-tuning & Deployment -- Convert and deploy custom fine-tunes
- Choose Your Binding -- Help picking the right binding for your project