188 lines
6.9 KiB
Markdown
188 lines
6.9 KiB
Markdown
# SUIME
|
||
|
||
**SUIME** 是一个用于学习的基于深度神经网络的输入法引擎项目。
|
||
|
||
- 🚀 **核心智能**:基于 Rust 构建的高性能推理服务端,支持 INT8 量化 ONNX 模型。
|
||
- 🐧 **原生 Linux 支持**:提供基于 `fcitx5` 的高性能插件。
|
||
- 🔌 **语言无关协议**:基于 MessagePack 的通用通信协议,允许任意语言编写前端。
|
||
|
||
---
|
||
|
||
## 🏗️ 整体架构
|
||
|
||
项目分为两个核心部分:**智能服务端** 和 **平台相关客户端**。两者通过高效的二进制协议通信。
|
||
|
||
```mermaid
|
||
graph TD
|
||
subgraph "AI Inference Server (Rust)"
|
||
S[Socket Listener<br/>UDS / TCP / Named Pipe]
|
||
M[ONNX Runtime Engine]
|
||
T[Tokenizer]
|
||
S --> M
|
||
M --> T
|
||
end
|
||
|
||
subgraph "Client Frontends"
|
||
L[Linux Client<br/>fcitx5-ext]
|
||
W[Windows Client<br/>Rime/Weasel Mod]
|
||
Mac[macOS Client<br/>Rime/Squirrel Mod]
|
||
end
|
||
|
||
L -- "Unix Domain Socket" --> S
|
||
W -- "TCP / Named Pipes" --> S
|
||
Mac -- "Unix Domain Socket / TCP" --> S
|
||
```
|
||
|
||
### 1. 服务端 (Rust)
|
||
- **并发模型**:使用 `std::thread` 或 `tokio` 处理多客户端连接。
|
||
- **推理引擎**:集成 `onnxruntime`,加载 INT8 量化模型以实现低延迟推理。
|
||
- **分词处理**:可选集成 `tokenizers` 库进行预处理。
|
||
- **通信适配**:
|
||
- **Linux/macOS**:默认使用 **Unix Domain Socket (UDS)**,利用文件系统路径通信,零拷贝,极低延迟。
|
||
- **Windows**:自动切换为 **TCP (localhost)** 或 **Named Pipes**,确保跨平台兼容性。
|
||
- **数据协议**:接收/发送 **MessagePack** 序列化的二进制数据。
|
||
|
||
### 2. 客户端 (Frontend)
|
||
- **Linux (当前实现)**:
|
||
- 基于 `fcitx5` 框架开发的 C++ 插件。
|
||
- 直接通过 UDS 与服务端通信。
|
||
- 负责捕获按键、获取上下文、渲染候选词面板。
|
||
---
|
||
|
||
## 📂 项目目录结构
|
||
|
||
### 目录
|
||
|
||
```text
|
||
SUIME/
|
||
├── Cargo.toml # Rust 服务端配置
|
||
├── src/ # Rust 服务端源码
|
||
│ ├── config.rs # 配置文件解析与加载,配置文件放在user_config_dir(类似~/.config/suime/config.toml),无配置可直接生成默认配置
|
||
│ ├── filter.rs # 对候选词进行转换和筛选,将OnnxModel::predict预测的结果进行转换,并根据用户输入的Request.pinyin进行匹配和筛选,返回候选字列表
|
||
│ ├── vocabs.rs # id和汉字转化
|
||
│ ├── personal.rs # 个性化词汇的登录、管理和查询(未来扩展)
|
||
│ ├── protocol.rs # 跨平台通用的请求/响应结构体 (MessagePack)
|
||
│ ├── main.rs # 入口:根据 OS 自动选择监听模式 (UDS/TCP)
|
||
│ ├── model.rs # ONNX 模型加载与推理封装
|
||
│ ├── socket.rs # 通信层抽象
|
||
│ └── tokenizer.rs # 分词器封装
|
||
├── fcitx5-ext/ # [Linux] fcitx5 插件源码
|
||
│ ├── CMakeLists.txt
|
||
│ ├── src/
|
||
│ │ ├── suime.cpp # 输入法逻辑
|
||
│ │ ├── socket_client.cpp # Linux UDS 客户端实现
|
||
│ │ └── protocol.hpp # 与服务端一致的协议定义
|
||
├── assets/ # ONNX 模型文件 & 词表
|
||
└── README.md
|
||
```
|
||
|
||
### 文件说明
|
||
|
||
- **filter.rs** 将OnnxModel::predict预测的结果转化为(汉字、拼音、权重),排除和用户输入的拼音不相符的汉字,比如用户输入的是shanghai,预测的结果为(上,商,尚,特,……),特将会被排除,为了简化,直接粗暴的将预测汉字的拼音首字母和用户输入的拼音首字母进行对比,相同视为相符,不相同视为不符。
|
||
|
||
---
|
||
|
||
## 🛠️ 技术细节与接口定义
|
||
|
||
### 通信协议 (Protocol)
|
||
为了保证跨语言和跨平台兼容性,应用层协议采用 **TLV (Type-Length-Value)** 风格封装 **MessagePack** 数据:
|
||
1. **Header**: 4 字节大端无符号整数 (`uint32_t`),表示后续 Payload 的长度。
|
||
2. **Payload**: MessagePack 序列化的二进制数据。
|
||
|
||
**数据结构定义 (`protocol.rs` / `protocol.hpp`):**
|
||
|
||
```rust
|
||
// Rust 服务端定义
|
||
use serde::{Serialize, Deserialize};
|
||
|
||
#[derive(Debug, Serialize, Deserialize)]
|
||
pub struct Request {
|
||
pub pinyin: String, // 用户输入的拼音串
|
||
pub context: String, // 光标前文本 (用于上下文预测)
|
||
}
|
||
|
||
#[derive(Debug, Serialize, Deserialize)]
|
||
pub struct Candidate {
|
||
pub id: u32, // 词项 ID
|
||
pub text: String, // 候选词文本 (也可由客户端查表)
|
||
pub weight: f32, // 置信度/权重
|
||
}
|
||
|
||
#[derive(Debug, Serialize, Deserialize)]
|
||
pub struct Response {
|
||
pub candidates: Vec<Candidate>,
|
||
pub offset: usize,
|
||
pub limit: usize,
|
||
}
|
||
```
|
||
|
||
### 跨平台 socket 适配策略
|
||
服务端代码使用 Rust 的条件编译 (`cfg`) 自动适配操作系统:
|
||
|
||
- **`#[cfg(unix)]`**:
|
||
- 使用 `std::os::unix::net::{UnixListener, UnixStream}`。
|
||
- 绑定路径:`/tmp/su-ime.sock` (可配置)。
|
||
- 优势:无需网络栈开销,权限控制基于文件系统。
|
||
- **`#[cfg(windows)]`**:
|
||
- 使用 `std::net::{TcpListener, TcpStream}`。
|
||
- 绑定地址:`127.0.0.1:23333` (可配置)。
|
||
- 优势:原生支持 Windows,便于穿透 WSL 或容器边界。
|
||
|
||
---
|
||
|
||
## 🗺️ 开发与部署路线图
|
||
- [ ] 完成 Rust 服务端 UDS 通信与 ONNX 推理。
|
||
- [ ] 完成 fcitx5 插件开发与联调。
|
||
- [ ] 性能优化:引入线程池,减少上下文切换开销。
|
||
- [ ] 打包:提供 `.deb` / `.rpm` 安装包及 systemd 用户服务配置。
|
||
|
||
---
|
||
|
||
## 🚀 快速开始 (Linux)
|
||
|
||
### 前置依赖
|
||
- Rust Toolchain (`rustup`)
|
||
- CMake, g++, pkg-config
|
||
- fcitx5 开发库 (`fcitx5-dev`, `libfcitx5utils-dev`)
|
||
- libmsgpack-c
|
||
|
||
### 构建服务端
|
||
```bash
|
||
cd SUIME
|
||
cargo build --release
|
||
# 二进制文件位于 target/release/su-ime
|
||
```
|
||
|
||
### 构建 fcitx5 插件
|
||
```bash
|
||
cd fcitx5-ext
|
||
mkdir build && cd build
|
||
cmake .. -DCMAKE_BUILD_TYPE=Release
|
||
make
|
||
sudo make install
|
||
```
|
||
|
||
### 运行
|
||
1. 启动服务端:
|
||
```bash
|
||
./target/release/su-ime --model ../models/model.onnx --socket /tmp/su-ime.sock
|
||
```
|
||
2. 重启 fcitx5 或在输入法设置中启用 "SUIME"。
|
||
3. 开始输入体验 AI 预测。
|
||
|
||
---
|
||
|
||
## ⚠️ 注意事项
|
||
|
||
1. **延迟敏感**:输入法对延迟极其敏感。在跨平台架构(特别是 Windows TCP 模式)下,需严格测试网络栈带来的额外延迟(通常 localhost TCP 延迟 < 0.1ms,可接受)。
|
||
2. **安全性**:
|
||
- Linux UDS 依赖文件权限,请确保 `/tmp/su-ime.sock` 仅对当前用户可见。
|
||
- Windows TCP 模式默认仅绑定 `127.0.0.1`,严禁绑定 `0.0.0.0` 以防外部攻击。
|
||
3. **服务保活**:建议配置 systemd (Linux) 或 Windows Service 来守护 Rust 服务端进程,确保其崩溃后能自动重启。
|
||
|
||
---
|
||
|
||
## 📄 许可证
|
||
|
||
本项目采用 MIT 许可证。
|