# jpy-ml
**Repository Path**: javpower/jpy-ml
## Basic Information
- **Project Name**: jpy-ml
- **Description**: 生产级 Java AI/ML 框架 — 6 行 Java 代码实现检测 · 分割 · 跟踪 · 分类 · 姿态 · 训练 · 验证 · 导出 · LLM 微调
- **Primary Language**: Unknown
- **License**: Apache-2.0
- **Default Branch**: main
- **Homepage**: https://i.m78cloud.cn/projects/9f489027-70f6-4f38-94f0-b56706951239/
- **GVP Project**: No
## Statistics
- **Stars**: 10
- **Forks**: 2
- **Created**: 2026-05-04
- **Last Updated**: 2026-05-09
## Categories & Tags
**Categories**: Uncategorized
**Tags**: Java, AI, Python
## README
# jpy-ml
**有史以来最强大的 Java AI/ML 框架。**
*一个依赖。零 Python 安装。完整 PyTorch。生产即用。*
检测 · 分割 · 跟踪 · 分类 · 姿态 · 训练 · 验证 · 导出 · LLM 微调 — **纯 Java 完成。**
[](https://central.sonatype.com/artifact/io.github.javpower/jpy-ml)
[](https://github.com/javpower/jpy-ml/actions/workflows/ci.yml)
[]()
[]()
[]()
[]()
[]()
English ·
快速开始 ·
API 文档 ·
路线图

---
## 为什么选择 jpy-ml?
jpy-ml 将**整个 Python ML 生态直接嵌入 JVM** — YOLO、SAM、MediaPipe、OpenCV、HuggingFace LLM — 全部封装为简洁、类型安全的 Java API,**零 Python 安装、零 REST 服务、零网络延迟**。
```java
// 3 行代码。自动下载模型,运行推理,返回类型化结果。
try (Model model = Model.preset("yolov8n")) {
DetectionResult result = model.predict("photo.jpg");
System.out.println(result.toJson()); // {"task":"detect","count":6,"boxes":[...]}
}
```
无需安装 Python。无需手动下载模型。无需配置文件。无需 `Map` 强转。无需微服务。
**生产级 ML,进程内运行,纯 Java 体验。**
### 唯一一个能同时做到这些的 Java 框架:
|
**计算机视觉**
- YOLOv8 / YOLO11 / YOLO26 / RT-DETR
- 检测、分割、分类、姿态、旋转框(OBB)
- 训练、验证、导出(ONNX/TensorRT/CoreML)
- 零拷贝 GPU 推理(`TensorBufferPool`)
|
**交互式分割**
- SAM 2 — 点/框提示 + 视频目标跟踪
- SAM 3 — 自然语言分割("找到所有车辆")
- CLIP 驱动的语义理解
|
|
**人体与人脸**
- MediaPipe — 手部追踪(21 关键点)
- 面部网格(478 关键点)、姿态估计(33 关键点)
|
**图像处理**
- OpenCV — 模糊、边缘检测、轮廓、形态学
- 颜色转换、阈值处理、缩放
|
|
**大语言模型**
- HuggingFace 模型下载与缓存
- 对话推理(`ChatMessage` API)
- LoRA/QLoRA 微调 + 实时回调
- 异步训练、适配器合并、量化
|
**生产级架构**
- 完整 PyTorch — CPU / Apple MPS / NVIDIA CUDA / 多卡
- 单 JVM 进程 — 无需 Python 服务
- 线程安全引擎(`ReadWriteLock`)
- 自动下载 Python、依赖、模型权重
|
### 传统方案 vs jpy-ml
| 传统 Java ML 方案 | jpy-ml |
|---|---|
| 通过 REST 调用 Python 服务 | ML **进程内运行**(JNI)— 零网络延迟 |
| 手动安装 Python + pip + torch | **自动下载** Python、所有依赖、模型权重 |
| 解析无类型的 JSON 结果 | **强类型**结果:`DetectionResult`、`PoseResult`... |
| 部署两个服务(Java + Python API) | **单 JVM 进程** — 运维更简单,成本更低 |
| 只能用 ONNX Runtime(仅 CPU) | **完整 PyTorch** — CPU、Apple MPS、NVIDIA CUDA、多卡 |
| 只能推理 | **推理 + 训练 + 验证 + 导出 + LLM 微调** — 全生命周期覆盖 |
---
## 特性
### 核心框架
- **嵌入式 Python 运行时** — 通过 Jep(JNI)将完整 CPython 嵌入 JVM,自动管理生命周期
- **零配置环境** — 生产模式自动下载 Python,开发模式使用本地 venv
- **线程安全引擎** — 单例 PythonEngine + ReadWriteLock,支持并发调用
- **类型安全 API** — 强类型配置、结果、回调 —— 用户代码无需 `Map` 强转
- **透明 Python 桥接** — 需要时可通过 `PythonEngine` 直接调用任意 Python/NumPy
- **SLF4J 日志** — 集成 Logback 日志框架
- **异常层次** — `JpyMlException` 基类 + 类型化异常
### 计算机视觉(Ultralytics YOLO)
- **统一 Model API** — 单一 `Model` 类支持所有架构和任务
- **6 个模型家族** — YOLOv8、YOLO11、YOLO26、RT-DETR、SAM,以及 ONNX Runtime 推理
- **5 种任务类型** — 检测、分割、分类、姿态估计、旋转框(OBB)
- **完整生命周期** — 推理、训练、验证、导出(ONNX/TensorRT/CoreML/TFLite/...)
- **丰富结果类型** — BoundingBox、Mask、Keypoint、RotatedBoundingBox,带过滤/查询辅助方法
- **设备抽象** — CPU / MPS(Apple Silicon)/ CUDA GPU / 多 GPU,通过 `Device` 类统一管理
- **Epoch 回调** — 实时训练进度,逐 epoch 的 loss/fitness 指标
- **逐类验证** — mAP50、mAP50-95、precision、recall 按类别细分
- **图像标注** — 通过 PIL 绘制推理结果,支持所有任务类型
- **零拷贝桥接** — `TensorBufferPool` + `RawDetectionResult` 高性能推理
- **GPU 内存管理** — `warmup()`、`unload()`、`reload(device)` API
- **直接图像输入** — `predict(byte[])`、`predict(BufferedImage)`,无需临时文件
- **异步 API** — `predictAsync()` 返回 `CompletableFuture`
- **结果序列化** — `toJson()`、`toMap()`,所有结果类型,无外部依赖
- **模型中心** — `Model.preset("yolov8n")` 自动下载并缓存模型
- **Java 可视化** — `ImageVisualizer` 纯 Java2D 绘制框/mask/关键点
### SAM 2 — 交互式分割
- **点/框提示** — 通过点击或绘制边界框分割对象
- **多提示组合** — 组合正向和负向提示
- **视频跟踪** — 利用时序记忆在视频帧间跟踪目标
- **SAM2Model** — 专用 SAM 2 推理模型类
- **SAM2Result** — 带 mask 和置信度的类型化结果
- **SAM2VideoTracker** — 视频目标跟踪,支持逐帧提示
### SAM 3 — 概念级分割
- **文本提示** — 使用自然语言分割目标("person"、"red car")
- **图像样本** — 使用参考图像区域查找相似目标
- **SAM3Model** — 专用 SAM 3 推理模型类
- **SAM3Result** — 带 mask、置信度和类别的类型化结果
- **CLIP 集成** — 使用 CLIP 实现文本到 mask 的语义理解
### OpenCV 集成
- **OpenCVEngine** — OpenCV 操作的 Java API
- **图像 I/O** — imread、imwrite,支持格式检测
- **颜色转换** — BGR2GRAY、BGR2RGB 等
- **滤波** — 高斯模糊、Canny 边缘检测、阈值处理
- **轮廓** — 查找和分析轮廓
- **形态学** — 膨胀、腐蚀、开运算、闭运算
### MediaPipe 集成
- **MediaPipeEngine** — MediaPipe 任务的 Java API
- **手部追踪** — 检测手部 21 个关键点
- **面部网格** — 检测面部 478 个关键点
- **姿态估计** — 检测身体 33 个关键点
### LLM — 大语言模型
- **LLMModel** — 统一入口:模型下载、推理、微调
- **HuggingFace Hub** — `LLMModel.download("Qwen/Qwen2.5-0.5B-Instruct")` 自动缓存
- **对话推理** — 类型化 `ChatResponse`,含 token 计数,支持 `ChatMessage` 角色化 API
- **LoRA/QLoRA 微调** — 基于 PEFT + TRL SFTTrainer 的参数高效训练
- **实时回调** — 逐 step 训练进度,通过 `TrainingCallback` 回调
- **异步训练** — `runAsync()` 返回 `CompletableFuture`
- **量化支持** — NF4/INT8(CUDA),根据平台自动选择
- **自动设备检测** — CPU / Apple MPS / NVIDIA CUDA 自动检测
- **LoRA 合并** — `LLMModel.mergeAdapter()` 将适配器合并回基座模型
- **生成配置** — temperature、top-p、max tokens、repetition penalty
- **自动依赖安装** — transformers、peft、trl、accelerate 首次使用时自动安装
### FLUX.1 — AI 图像生成
- **FluxModel** — 文本生成图像的统一入口
- **FLUX.1 Dev** — 高质量版本,20 步推理,需要 HuggingFace 授权
- **FLUX.1 Schnell** — 快速版本,4 步推理,Apache 2.0 许可
- **文本到图像** — `flux.generate("A cat in space", "output.png")`
- **图像到图像** — `flux.img2img(prompt, inputPath, outputPath, config)`
- **自定义配置** — 宽度、高度、步数、引导强度、种子
- **自动设备检测** — CPU / Apple MPS / NVIDIA CUDA
- **按需依赖** — 首次使用时自动安装 diffusers、transformers 等
---
## Maven
```xml
io.github.javpower
jpy-ml
1.4.0
```
---
## 环境要求
| 组件 | 版本 | 备注 |
|------|------|------|
| JDK | Temurin 17 | 通过 sdkman,**不要用 GraalVM**(JNI 崩溃) |
| Python | 3.12(自动下载) | python-build-standalone,用户无需安装 |
| Jep (pip + Maven) | 4.3.1 | Java-Python JNI 桥接,Maven groupId: `org.ninia` |
| Ultralytics | 8.4.45 | YOLOv8, YOLO11, YOLO26, RT-DETR, SAM |
| OpenCV | 4.6.0+ | 图像处理(可选) |
| MediaPipe | 0.10.0+ | 手部/面部/姿态检测(可选) |
| PyTorch | 2.11.0 | CPU-only macOS ARM64 |
| OS | Linux、macOS、Windows | 三个平台均通过 CI 测试 |
### 依赖管理
**两种初始化模式:**
| 模式 | 方法 | 自动安装 | 使用场景 |
|------|------|----------|----------|
| **自动下载** | `PythonRuntime.init()` | ✅ 是 | 生产环境,零配置 |
| **本地venv** | `PythonRuntime.init(pythonPath, jepLibPath)` | ❌ 否 | 开发环境,已有Python |
**自动下载模式** (`PythonRuntime.init()`):
- 自动下载 python-build-standalone
- 自动安装 `requirements.txt` 中的所有依赖
**本地venv模式** (`PythonRuntime.init(pythonPath, jepLibPath)`):
- 使用现有Python环境
- 需手动安装依赖:
```bash
.venv/bin/pip install -r src/main/resources/requirements.txt
```
---
## 快速开始
### 1. 切换 JDK 17
```bash
sdk install java 17.0.19-tem # 首次安装
sdk use java 17.0.19-tem
java -version # 确认: openjdk 17.0.19 Temurin
```
### 2. 创建 Python 虚拟环境
```bash
/opt/homebrew/bin/python3.13 -m venv .venv
```
### 3. 安装 Python 依赖
```bash
# 基础依赖(必须)
.venv/bin/pip install jep numpy ultralytics
# 可选:OpenCV 图像处理
.venv/bin/pip install opencv-python
# 可选:MediaPipe 手部/面部/姿态检测
.venv/bin/pip install mediapipe
# 或一次性安装所有依赖
.venv/bin/pip install -r src/main/resources/requirements.txt
```
### 4. 构建与测试
```bash
mvn clean test
# 预期: Tests run: 72, Failures: 0, Errors: 0, Skipped: 6
```
---
## CLI 使用
jpy-ml 提供了命令行界面,让您无需编写 Java 代码即可使用各种 ML 功能。
### 构建 CLI
```bash
mvn package -Pcli -DskipTests
```
### 使用 CLI
```bash
# 查看帮助
./bin/jpy-ml --help
# 目标检测
./bin/jpy-ml predict -m yolov8n.pt -s photo.jpg
# 图像分类
./bin/jpy-ml classify -m yolov8n-cls.pt -s photo.jpg
# 姿态估计
./bin/jpy-ml pose -m yolov8n-pose.pt -s person.jpg
# SAM 分割
./bin/jpy-ml segment -m sam2.1_t.pt -i photo.jpg -p 320,240
# YOLO 模型训练
./bin/jpy-ml yolo-train -m yolov8n.pt -d coco128.yaml --epochs 50
# 模型验证
./bin/jpy-ml validate -m yolov8n.pt -d coco128.yaml
# 模型导出
./bin/jpy-ml export -m yolov8n.pt -f onnx
# LLM 对话
./bin/jpy-ml chat -m Qwen/Qwen2.5-0.5B-Instruct --message "你好"
# LLM 微调
./bin/jpy-ml train -m Qwen/Qwen2.5-0.5B-Instruct -d training_data.jsonl
# 列出可用模型
./bin/jpy-ml list-models
# 下载模型
./bin/jpy-ml download -n yolov8n.pt
# FLUX.1 图像生成
./bin/jpy-ml generate -p "A cat in space" -o cat.png
# FLUX.1 高质量生成
./bin/jpy-ml generate -m dev -p "A beautiful sunset" -o sunset.png --steps 30
```
更多 CLI 用法请参考 [CLI 使用指南](CLI_USAGE_zh.md)。
---
## API 用法
### 模型加载 — 指定任务类型和设备
```java
// 自动检测任务类型
try (Model model = new Model("yolov8n.pt")) { ... }
// 显式指定任务类型(适用于自定义命名的模型)
try (Model model = new Model("my_model.pt", TaskType.DETECT)) { ... }
// 指定设备
ModelConfig config = new ModelConfig()
.device(Device.cpu()); // CPU
.device(Device.mps()); // Apple Silicon GPU
.device(Device.gpu(0)); // GPU 0
.device(Device.cuda(0)); // CUDA:0
```
### 目标检测
```java
try (Model model = new Model("yolov8n.pt")) {
DetectionResult result = model.predict("photo.jpg");
for (ClassPrediction pred : result.getBoxes()) {
System.out.println(pred);
// person 92.3% BoundingBox[x1=100.5, y1=50.2, x2=300.1, y2=400.8]
}
// 过滤结果
List persons = result.filterByClass("person");
List confident = result.filterByConfidence(0.8f);
}
```
### 实例分割
```java
try (Model model = new Model("yolov8n-seg.pt")) {
SegmentationResult result = model.predict("photo.jpg");
for (int i = 0; i < result.getBoxes().size(); i++) {
ClassPrediction pred = result.getBoxes().get(i);
Mask mask = result.getMasks().get(i);
System.out.println(pred.className() + " 掩码点数: " + mask.getPointCount());
}
}
```
### 图像分类
```java
try (Model model = new Model("yolov8n-cls.pt")) {
ClassificationResult result = model.predict("photo.jpg");
System.out.println("预测: " + result.getTop1ClassName());
System.out.println("置信度: " + result.getTop1Confidence());
}
```
### 姿态估计
```java
try (Model model = new Model("yolov8n-pose.pt")) {
PoseResult result = model.predict("photo.jpg");
for (int i = 0; i < result.personCount(); i++) {
KeypointCollection kpts = result.getKeypoints().get(i);
Keypoint nose = kpts.getNose();
System.out.printf("人物 %d: 鼻子=(%.1f, %.1f)%n", i, nose.x(), nose.y());
}
}
```
### 旋转框检测 (OBB)
```java
try (Model model = new Model("yolov8n-obb.pt")) {
OBBResult result = model.predict("satellite_image.jpg");
for (OBBPrediction pred : result.getPredictions()) {
RotatedBoundingBox box = pred.box();
System.out.printf("%s %.1f%% 角度=%.1f°%n",
pred.className(), pred.confidence() * 100, box.angleDegrees());
}
}
```
### 推理配置
```java
ModelConfig config = new ModelConfig()
.confidence(0.5f) // 置信度阈值
.iouThreshold(0.7f) // NMS IoU 阈值
.imageSize(640) // 输入图像尺寸
.maxDetections(100) // 最大检测数
.device(Device.gpu(0)) // 设备选择
.augment(true) // 测试时增强
.filterClasses(0, 2, 5) // 只检测指定类别
.half(true) // FP16 推理(GPU)
.verbose(false) // 静默模式
.save(true) // 保存结果
.embed(0, 1, 2); // 提取特征嵌入
InferenceResult result = model.predict("photo.jpg", config);
```
### ONNX 推理
```java
// 加载 ONNX 模型(推荐显式指定任务类型)
try (Model model = new Model("yolov8n.onnx", TaskType.DETECT)) {
DetectionResult result = model.predict("photo.jpg");
}
// 导出为 ONNX
ExportResult exported = model.export(ExportFormat.ONNX);
```
### 模型训练
```java
TrainingConfig config = new TrainingConfig()
.dataConfig("coco128.yaml")
.epochs(50)
.batchSize(16)
.device(Device.gpu(0))
.optimizer(OptimizerType.ADAMW)
.learningRate(0.001f)
.augmentation(new AugmentationConfig()
.mosaic(true)
.fliplr(0.5f)
.hsvH(0.015f));
// 带 epoch 回调
TrainingResult result = model.train(config, (epoch, log) -> {
System.out.println("Epoch " + epoch + ": " + log);
});
// 查看 epoch 级别指标
for (EpochMetric m : result.getEpochMetrics()) {
System.out.printf("Epoch %d: box_loss=%.4f cls_loss=%.4f%n",
m.epoch(), m.boxLoss(), m.clsLoss());
}
```
### 模型验证
```java
ValidationResult val = model.validate("coco128.yaml");
System.out.printf("mAP50=%.3f, mAP50-95=%.3f, P=%.3f, R=%.3f%n",
val.getMAP50(), val.getMAP5095(), val.getPrecision(), val.getRecall());
// 每个类别的指标
for (PerClassMetric pc : val.getPerClassMetrics()) {
System.out.println(pc); // "person (id=0): mAP50-95=0.7234"
}
```
### 批量推理
```java
try (Model model = new Model("yolov8n.pt")) {
List images = List.of("photo1.jpg", "photo2.jpg", "photo3.jpg");
List results = model.predict(images);
for (int i = 0; i < results.size(); i++) {
System.out.println("图像 " + i + ": " + results.get(i).count() + " 个目标");
}
}
```
### 视频流式推理
```java
try (Model model = new Model("yolov8n.pt")) {
// 视频文件 — 逐帧分块流式处理
model.predictVideo("video.mp4", frame -> {
System.out.println("帧: " + frame.count() + " 个目标");
});
// 摄像头 — 实时推理(阻塞当前线程)
// 在另一个线程调用 stopStream() 停止
new Thread(() -> {
Thread.sleep(10000);
model.stopStream(); // 10 秒后停止
}).start();
model.predictStream(0, frame -> {
// 0 = 默认摄像头
if (frame instanceof DetectionResult dr) {
System.out.println("摄像头: " + dr.getBoxes().size() + " 个目标");
}
});
}
```
### LLM — 下载与对话推理
```java
// 从 HuggingFace Hub 下载模型(缓存到 ~/.jpy-ml/llm-models/)
LLMModel model = LLMModel.download("Qwen/Qwen2.5-0.5B-Instruct");
// 或从本地路径加载
LLMModel model = LLMModel.load("/path/to/local/model");
// 对话推理
ChatResponse response = model.chat(
ChatMessage.system("你是一个有用的助手"),
ChatMessage.user("你好,请用一句话介绍你自己")
);
System.out.println(response.getContent());
System.out.println("Tokens: prompt=" + response.getPromptTokens()
+ " completion=" + response.getCompletionTokens());
// 带生成配置
ChatResponse response = model.chat(
List.of(
ChatMessage.system("你是一个有用的助手"),
ChatMessage.user("解释量子计算")
),
GenerationConfig.create()
.maxNewTokens(256)
.temperature(0.7)
.topP(0.9)
.repetitionPenalty(1.1)
);
```
### LLM — LoRA 微调
```java
LLMModel model = LLMModel.load("Qwen/Qwen2.5-0.5B-Instruct")
.quantize(Quantization.NONE); // macOS
// 同步微调,带实时回调
LLMTrainingResult result = model.fineTune()
.lora(LoRAConfig.create().rank(8).alpha(16))
.dataset("training_data.jsonl")
.config(LLMTrainConfig.create()
.epochs(3)
.batchSize(4)
.gradientAccumulation(4)
.learningRate(2e-4)
.maxSeqLength(2048)
.gradientCheckpointing(true))
.run((step, log) -> {
System.out.println("Step " + step + ": " + log);
});
System.out.println("适配器保存到: " + result.getAdapterPath());
System.out.println("最终 loss: " + result.getFinalLoss());
```
### LLM — 加载适配器推理
```java
// 加载基座模型 + 训练好的 LoRA 适配器
LLMModel finetuned = LLMModel.load("Qwen/Qwen2.5-0.5B-Instruct")
.adapter("/path/to/adapter");
ChatResponse response = finetuned.chat(
ChatMessage.user("你叫什么名字?")
);
System.out.println(response.getContent());
```
### LLM — 异步微调
```java
CompletableFuture future = model.fineTune()
.lora(LoRAConfig.create().rank(4).alpha(8))
.dataset("data.jsonl")
.config(LLMTrainConfig.create().epochs(2))
.runAsync((step, log) -> {
System.out.println("[异步] " + log);
});
// 做其他事情...
LLMTrainingResult result = future.get(10, TimeUnit.MINUTES);
```
### LLM — 合并适配器到基座模型
```java
LLMTrainingResult result = model.fineTune()
.dataset("data.jsonl")
.config(LLMTrainConfig.create().epochs(3))
.run();
// 将 LoRA 适配器合并到基座模型,用于独立部署
String mergedPath = LLMModel.mergeAdapter(
model.getModelPath(),
result.getAdapterPath(),
"/path/to/merged-model"
);
```
### LLM — 训练数据格式(JSONL)
```json
{"messages": [{"role": "user", "content": "1+1=?"}, {"role": "assistant", "content": "1+1=2"}]}
{"messages": [{"role": "user", "content": "什么是Java?"}, {"role": "assistant", "content": "Java是一种编程语言。"}]}
```
也支持 instruction 格式:
```json
{"instruction": "翻译成英文", "input": "你好", "output": "Hello"}
```
### FLUX.1 — 文本生成图像
```java
// 快速生成(Schnell,4 步)
try (FluxModel flux = new FluxModel("black-forest-labs/FLUX.1-schnell")) {
FluxResult result = flux.generate("A cat in space", "cat.png");
System.out.println("输出: " + result.getFirstOutputPath());
System.out.println("耗时: " + result.getElapsedSeconds() + "s");
}
// 高质量生成(Dev,20 步)
FluxConfig config = FluxConfig.dev()
.width(1920)
.height(1080)
.steps(30)
.guidance(7.5f)
.seed(42);
try (FluxModel flux = new FluxModel("black-forest-labs/FLUX.1-dev")) {
FluxResult result = flux.generate("A beautiful sunset", "sunset.png", config);
}
// 图像到图像
try (FluxModel flux = new FluxModel("black-forest-labs/FLUX.1-schnell")) {
FluxResult result = flux.img2img(
"Oil painting style", "input.png", "output.png",
new FluxConfig().steps(10)
);
}
```
---
## 架构
```
┌──────────────────────────────────────────┐
│ 用户 Java 代码 │
│ Model m = new Model("yolov8n.pt"); │
│ DetectionResult r = m.predict(img); │
├──────────────────────────────────────────┤
│ Model / ModelConfig / Result 类型 │
│ (58 个 Java 源文件) │
├──────────────────────────────────────────┤
│ PythonEngine (单例, ReadWriteLock) │
│ SharedInterpreter + sys.path 过滤 │
├──────────────────────────────────────────┤
│ Jep 4.3.1 (JNI 桥接) │
│ libjep.jnilib 来自 pip install jep │
├──────────────────────────────────────────┤
│ Python 辅助脚本 (12 个 .py 文件) │
│ jpy_load_model / jpy_extract_result / │
│ jpy_train / jpy_export / jpy_validate / │
│ jpy_sam2 / jpy_sam3 / jpy_opencv / │
│ jpy_mediapipe / jpy_streaming / ... │
├──────────────────────────────────────────┤
│ CPython 3.13 (.venv) │
│ Ultralytics 8.4.45 + PyTorch 2.11 │
└──────────────────────────────────────────┘
```
---
## 测试覆盖
全部 110 个测试通过(0 跳过):
| 测试套件 | 数量 | 说明 |
|---------|------|------|
| QuickVerifyTest | 10 | 基础 Python 桥接(eval、put/get、numpy、列表、字典) |
| PythonEngineTest | 11 | 引擎特性(多线程、回调、模块) |
| PythonRuntimeTest | 3 | 平台检测 |
| ModelIntegrationTest | 18 | 完整 YOLO 集成(推理 + 批量 + 视频 + 训练 + 导出) |
| SAMIntegrationTest | 9 | SAM 2/3 集成(点/框/视频/文本/样本) |
| LLMIntegrationTest | 4 | LLM 下载、对话、LoRA 微调、异步训练 |
| NewFeaturesTest | 17 | 序列化、byte[]输入、异步、模型中心、可视化 |
| TensorBufferPoolTest | 6 | 零拷贝缓冲池 |
| BoundingBoxTest | 10 | BoundingBox 记录类 |
| KeypointTest | 5 | Keypoint 记录类 |
| InferenceSpeedTest | 5 | InferenceSpeed 记录类 |
| MediaPipeEngineTest | 4 | 手部/面部/姿态检测 |
| OpenCVEngineTest | 8 | 图像处理操作 |
覆盖范围:
- 5 种任务类型:检测、分割、分类、姿态、OBB
- PyTorch 和 ONNX 模型推理
- YOLOv8 和 YOLO26 模型
- SAM 2 交互式分割 + 视频跟踪
- SAM 3 文本提示 + 图像样本分割
- LLM 模型下载、对话推理、LoRA/QLoRA 微调(含异步训练)
- MediaPipe 手部(21 关键点)、面部(478 关键点)、姿态(33 关键点)
- OpenCV 图像处理(颜色转换、滤波、边缘检测、轮廓、形态学)
- 训练(含 epoch 回调和指标)
- 验证(含每类别 mAP)
- ONNX 导出
- 训练后加载模型推理
---
## 关键设计
1. **单例 PythonEngine** — Jep 限制每个 JVM 只能有一个 SharedInterpreter。所有 Model 实例通过唯一变量名前缀共享。
2. **Python 脚本做重活** — 复杂的 tensor→dict 转换在 Python 端完成,Java 只接收 `Map`。
3. **sys.path 过滤** — 自动过滤 Homebrew 系统包路径冲突,优先使用 venv 的 site-packages。
4. **AutoCloseable Model** — `Model implements AutoCloseable`,close 时将 Python 变量设为 `None` 便于 GC。
5. **Builder 模式** — 所有配置类(`ModelConfig`、`TrainingConfig`、`ExportConfig`、`AugmentationConfig`)使用链式调用。
---
## 常见问题
### JVM 崩溃 (Abort trap: 6)
**原因:** 使用了 GraalVM CE。
**解决:** 切换到标准 OpenJDK(Temurin)。
### "Jep native library not found"
**原因:** venv 中未安装 jep。
**解决:** `.venv/bin/pip install jep`
### "ultralytics not installed" 或 opencv dlopen 错误
**原因:** Homebrew site-packages 路径与 venv 冲突。
**解决:** 使用 `PythonRuntime.init(pythonPath, jepLibPath)` 传入 venv 路径,PythonEngine 会自动过滤冲突路径。
---
## 路线图
jpy-ml 的定位是通用 Java-Python ML 桥接框架。YOLO 是第一个引擎 —— 更多引擎正在路上。
### 已完成
- [x] 批量推理 API(`model.predict(List)`)
- [x] 摄像头/视频流实时推理
- [x] python-build-standalone 自动下载(终端用户无需安装 Python)
- [x] PyTorch tensor 零拷贝桥接(`TensorBufferPool` + `RawDetectionResult`)
- [x] GPU 显存管理与模型预热 API
- [x] SAM 2 交互式分割(点/框提示)
- [x] SAM 2 视频跟踪(逐帧提示 + 时序记忆)
- [x] SAM 3 概念级分割(文本提示 + 图像样本)
- [x] OpenCV 集成(图像处理)
- [x] MediaPipe 集成(手部/面部/姿态)
- [x] SLF4J 日志框架
- [x] 异常层次(`JpyMlException` 基类)
- [x] CI/CD(GitHub Actions)
- [x] 结果序列化(toJson / toMap)
- [x] 直接图像输入(byte[] / BufferedImage)
- [x] 模型中心自动下载(Model.preset)
- [x] Java2D 结果可视化(ImageVisualizer)
- [x] 异步推理 API(predictAsync)
- [x] LLM 对话推理(HuggingFace Transformers)
- [x] LoRA/QLoRA 微调,带实时 step 回调
- [x] 异步微调 API(runAsync)
- [x] LoRA 适配器合并到基座模型
- [x] LLM 依赖自动安装(transformers、peft、trl、accelerate)
### 近期
- [ ] 所有值类型的单元测试
### 计划中的 ML 引擎
#### 其他引擎
- [ ] **Whisper** — 语音识别、语音转文字
- [ ] **Stable Diffusion / FLUX** — 图像生成、局部重绘、ControlNet
### 基础设施
- [ ] 模型仓库 / Hub 集成(从 URL 下载)
- [ ] Spring Boot Starter 自动配置
- [ ] GraalVM Native Image 支持