|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| mod inference;
|
| mod ledger;
|
| mod session;
|
| mod server;
|
| mod types;
|
|
|
| use std::sync::Arc;
|
|
|
| use clap::Parser;
|
| use tokio::sync::mpsc;
|
|
|
| use crate::ledger::run_ledger_worker;
|
| use crate::inference::run_inference_daemon;
|
| use crate::session::build_trt_session;
|
| use crate::server::{AppState, build_router};
|
| use crate::types::DaemonConfig;
|
|
|
| #[derive(Parser, Debug)]
|
| #[command(name = "bert-daemon", about = "Cross-Encoder entailment inference daemon")]
|
| struct Cli {
|
| #[arg(short, long, default_value = "config/daemon.json")]
|
| config: String,
|
| }
|
|
|
| #[tokio::main]
|
| async fn main() -> anyhow::Result<()> {
|
| env_logger::init();
|
| let cli = Cli::parse();
|
|
|
|
|
| let cfg: DaemonConfig = {
|
| let raw = std::fs::read_to_string(&cli.config)
|
| .unwrap_or_else(|_| {
|
| log::warn!("config not found at {}, using defaults", cli.config);
|
| serde_json::to_string(&DaemonConfig::default()).unwrap()
|
| });
|
| serde_json::from_str(&raw)?
|
| };
|
| let cfg = Arc::new(cfg);
|
| log::info!("[main] config loaded: model={} threshold={}", cfg.model_path, cfg.threshold);
|
|
|
|
|
| log::info!("[main] initialising TensorRT session...");
|
| let session = Arc::new(build_trt_session(&cfg)?);
|
| log::info!("[main] TRT session ready");
|
|
|
|
|
| let tokenizer = Arc::new(
|
| tokenizers::Tokenizer::from_pretrained(
|
| "microsoft/deberta-v3-base",
|
| None,
|
| ).expect("tokenizer load failed β run training first or place tokenizer/ in working dir"),
|
| );
|
|
|
|
|
|
|
| let (inference_tx, inference_rx) = mpsc::channel::<crate::types::VerifyRequest>(10_000);
|
|
|
| let (ledger_tx, ledger_rx) = mpsc::channel::<([u8; 32], Vec<u8>)>(10_000);
|
|
|
|
|
| let ledger_path = cfg.ledger_path.clone();
|
| tokio::spawn(async move {
|
| run_ledger_worker(ledger_rx, ledger_path).await;
|
| });
|
| log::info!("[main] WORM ledger worker spawned");
|
|
|
|
|
| {
|
| let session = Arc::clone(&session);
|
| let cfg_clone = Arc::clone(&cfg);
|
| let ledger_tx = ledger_tx.clone();
|
| tokio::spawn(async move {
|
| run_inference_daemon(inference_rx, session, cfg_clone, ledger_tx).await;
|
| });
|
| }
|
| log::info!("[main] inference daemon spawned β batch={} flush={}ms",
|
| cfg.max_batch_size, cfg.flush_interval_ms);
|
|
|
|
|
| let app_state = Arc::new(AppState {
|
| tx: inference_tx,
|
| cfg: Arc::clone(&cfg),
|
| tokenizer,
|
| });
|
| let router = build_router(app_state);
|
| let addr = format!("0.0.0.0:{}", cfg.http_port);
|
| log::info!("[main] HTTP server β {}", addr);
|
|
|
| let listener = tokio::net::TcpListener::bind(&addr).await?;
|
| axum::serve(listener, router).await?;
|
|
|
| Ok(())
|
| }
|
|
|