software copyright

This commit is contained in:
jiahong
2026-03-22 15:24:40 +08:00
parent e303bb868a
commit 60f336e345
155 changed files with 127262 additions and 0 deletions
@@ -0,0 +1,499 @@
/**
* 自然写教室智能算力盒边缘计算软件 V1.0
* 推理引擎模块 - ONNX Runtime / TensorRT 推理执行引擎
*
* 负责加载AI模型并执行推理任务
* 支持多种推理后端:ONNX Runtime、TensorRT、PaddleLite
* 支持NPU/GPU硬件加速调度
*/
#ifndef INFERENCE_ENGINE_H
#define INFERENCE_ENGINE_H
#include <string>
#include <vector>
#include <memory>
#include <mutex>
#include <queue>
#include <thread>
#include <atomic>
#include <chrono>
#include <functional>
#include <unordered_map>
#include <condition_variable>
// ==================== 数据结构定义 ====================
/**
* 推理设备类型枚举
* 算力盒支持多种硬件加速设备
*/
enum class DeviceType {
CPU = 0, // CPU推理(兜底方案)
GPU_CUDA = 1, // NVIDIA GPU (CUDA)
GPU_OPENCL = 2, // 通用GPU (OpenCL)
NPU_RKNN = 3, // 瑞芯微NPU (RKNN)
NPU_AMLOGIC = 4 // 晶晨NPU
};
/**
* 模型格式枚举
*/
enum class ModelFormat {
ONNX = 0, // ONNX格式(通用)
TENSORRT = 1, // TensorRT引擎(NVIDIA优化)
PADDLE_LITE = 2,// PaddleLiteARM优化)
RKNN = 3 // RKNN格式(瑞芯微NPU专用)
};
/**
* 推理任务类型
*/
enum class TaskType {
OCR = 0, // 文字OCR识别
MATH_RECOGNITION = 1, // 数学列式识别
STROKE_ORDER = 2, // 笔顺分析
WRITING_QUALITY = 3 // 书写质量评测
};
/**
* 张量数据(推理输入/输出)
* 封装多维数组数据和形状信息
*/
struct Tensor {
std::vector<float> data; // 浮点数据
std::vector<int64_t> shape; // 维度形状 (如 [1, 3, 64, 64])
std::string name; // 张量名称
/** 获取数据元素总数 */
size_t size() const {
size_t s = 1;
for (auto d : shape) s *= d;
return s;
}
};
/**
* 推理请求
*/
struct InferenceRequest {
std::string request_id; // 请求唯一ID
TaskType task_type; // 任务类型
std::vector<Tensor> inputs; // 输入张量列表
int priority = 2; // 优先级 (0=最高)
int timeout_ms = 500; // 超时时间
std::string pen_id; // 来源笔设备ID
std::string student_id; // 学生ID
std::chrono::steady_clock::time_point submit_time; // 提交时间
};
/**
* 推理结果
*/
struct InferenceResult {
std::string request_id;
bool success = false;
std::string error_message;
std::vector<Tensor> outputs; // 输出张量列表
float inference_time_ms = 0.0f; // 推理耗时
std::string model_version; // 使用的模型版本
};
// ==================== 推理后端抽象 ====================
/**
* 推理后端抽象基类
* 所有推理引擎(ONNX Runtime、TensorRT等)的统一接口
*/
class InferenceBackend {
public:
virtual ~InferenceBackend() = default;
/** 加载模型文件 */
virtual bool load_model(const std::string& model_path) = 0;
/** 执行推理 */
virtual InferenceResult infer(const InferenceRequest& request) = 0;
/** 卸载模型释放资源 */
virtual void unload() = 0;
/** 获取后端名称 */
virtual std::string name() const = 0;
};
/**
* ONNX Runtime推理后端
* 支持CPU/GPU/NPU多种执行提供者
*/
class OnnxRuntimeBackend : public InferenceBackend {
public:
OnnxRuntimeBackend(DeviceType device) : device_(device), loaded_(false) {}
bool load_model(const std::string& model_path) override {
model_path_ = model_path;
// 实际环境中:
// Ort::SessionOptions options;
// if (device_ == DeviceType::GPU_CUDA) {
// OrtCUDAProviderOptions cuda_opts;
// cuda_opts.device_id = 0;
// options.AppendExecutionProvider_CUDA(cuda_opts);
// }
// session_ = std::make_unique<Ort::Session>(env, model_path.c_str(), options);
loaded_ = true;
return true;
}
InferenceResult infer(const InferenceRequest& request) override {
InferenceResult result;
result.request_id = request.request_id;
if (!loaded_) {
result.success = false;
result.error_message = "模型未加载";
return result;
}
auto start = std::chrono::steady_clock::now();
// 执行ONNX Runtime推理
// std::vector<Ort::Value> input_tensors;
// for (const auto& input : request.inputs) {
// auto tensor = Ort::Value::CreateTensor<float>(
// memory_info, input.data.data(), input.size(),
// input.shape.data(), input.shape.size());
// input_tensors.push_back(std::move(tensor));
// }
// auto output_tensors = session_->Run(run_options, input_names, input_tensors, output_names);
// 模拟推理输出
Tensor output;
output.name = "output";
output.shape = {1, 10};
output.data.resize(10, 0.1f);
result.outputs.push_back(output);
result.success = true;
auto end = std::chrono::steady_clock::now();
result.inference_time_ms = std::chrono::duration<float, std::milli>(end - start).count();
return result;
}
void unload() override {
loaded_ = false;
}
std::string name() const override { return "ONNXRuntime"; }
private:
DeviceType device_;
std::string model_path_;
bool loaded_;
};
/**
* TensorRT推理后端
* NVIDIA GPU专用高性能推理引擎
* 支持FP16/INT8量化推理,显著降低推理延迟
*/
class TensorRTBackend : public InferenceBackend {
public:
TensorRTBackend() : loaded_(false) {}
bool load_model(const std::string& engine_path) override {
engine_path_ = engine_path;
// 实际环境中:
// std::ifstream file(engine_path, std::ios::binary);
// file.seekg(0, std::ios::end);
// size_t size = file.tellg();
// file.seekg(0, std::ios::beg);
// std::vector<char> engine_data(size);
// file.read(engine_data.data(), size);
//
// auto runtime = nvinfer1::createInferRuntime(logger);
// engine_ = runtime->deserializeCudaEngine(engine_data.data(), size);
// context_ = engine_->createExecutionContext();
loaded_ = true;
return true;
}
InferenceResult infer(const InferenceRequest& request) override {
InferenceResult result;
result.request_id = request.request_id;
if (!loaded_) {
result.success = false;
result.error_message = "TensorRT引擎未加载";
return result;
}
auto start = std::chrono::steady_clock::now();
// 执行TensorRT推理
// cudaMemcpyAsync(gpu_input, request.inputs[0].data.data(), ...);
// context_->enqueueV2(buffers, stream, nullptr);
// cudaMemcpyAsync(cpu_output, gpu_output, ...);
// cudaStreamSynchronize(stream);
Tensor output;
output.name = "output";
output.shape = {1, 10};
output.data.resize(10, 0.1f);
result.outputs.push_back(output);
result.success = true;
auto end = std::chrono::steady_clock::now();
result.inference_time_ms = std::chrono::duration<float, std::milli>(end - start).count();
return result;
}
void unload() override {
loaded_ = false;
}
std::string name() const override { return "TensorRT"; }
private:
std::string engine_path_;
bool loaded_;
};
// ==================== 推理任务队列 ====================
/**
* 优先级推理任务队列
* 按优先级和提交时间排序,高优先级任务优先处理
* 课堂实时场景的推理请求拥有最高优先级
*/
class InferenceTaskQueue {
public:
InferenceTaskQueue(size_t max_size = 1024) : max_size_(max_size) {}
/**
* 提交推理请求到队列
* 如果队列已满,丢弃最低优先级的任务
*/
bool enqueue(InferenceRequest request) {
std::lock_guard<std::mutex> lock(mutex_);
if (queue_.size() >= max_size_) {
// 队列已满,检查是否可以替换低优先级任务
if (!queue_.empty() && queue_.top().priority > request.priority) {
queue_.pop(); // 移除最低优先级任务
} else {
return false; // 无法入队
}
}
request.submit_time = std::chrono::steady_clock::now();
queue_.push(std::move(request));
cv_.notify_one();
return true;
}
/**
* 从队列获取最高优先级的任务
* 如果队列为空则阻塞等待
*/
bool dequeue(InferenceRequest& request, int timeout_ms = 100) {
std::unique_lock<std::mutex> lock(mutex_);
if (cv_.wait_for(lock, std::chrono::milliseconds(timeout_ms),
[this] { return !queue_.empty(); })) {
request = queue_.top();
queue_.pop();
return true;
}
return false;
}
size_t size() const {
std::lock_guard<std::mutex> lock(mutex_);
return queue_.size();
}
private:
// 自定义比较器:优先级小的排前面,相同优先级按提交时间排序
struct RequestCompare {
bool operator()(const InferenceRequest& a, const InferenceRequest& b) {
if (a.priority != b.priority) return a.priority > b.priority;
return a.submit_time > b.submit_time;
}
};
std::priority_queue<InferenceRequest, std::vector<InferenceRequest>, RequestCompare> queue_;
mutable std::mutex mutex_;
std::condition_variable cv_;
size_t max_size_;
};
// ==================== 推理引擎(核心类) ====================
/**
* 推理引擎
* 管理多个推理后端,根据模型类型和硬件条件选择最优推理路径
* 支持:
* - 多模型并发推理(OCR、数学、笔顺各独立模型)
* - 动态批处理(攒批提升GPU利用率)
* - 推理结果缓存(相同输入直接返回缓存结果)
* - 超时控制和优雅降级
*/
class InferenceEngine {
public:
InferenceEngine(DeviceType device, const std::string& models_dir)
: device_(device), models_dir_(models_dir), running_(false) {}
/**
* 初始化推理引擎
* 检测硬件设备、创建推理后端、加载模型
*/
bool initialize() {
// 检测硬件加速设备
detect_hardware();
// 为每种任务类型创建专用推理后端
backends_[TaskType::OCR] = create_backend("ocr");
backends_[TaskType::MATH_RECOGNITION] = create_backend("math");
backends_[TaskType::STROKE_ORDER] = create_backend("stroke_order");
backends_[TaskType::WRITING_QUALITY] = create_backend("writing_quality");
// 加载各模型
for (auto& [type, backend] : backends_) {
std::string model_file = get_model_path(type);
if (!backend->load_model(model_file)) {
return false;
}
}
// 启动推理工作线程
running_ = true;
worker_thread_ = std::thread(&InferenceEngine::worker_loop, this);
return true;
}
/**
* 提交推理请求(异步)
*/
std::string submit(InferenceRequest request) {
task_queue_.enqueue(std::move(request));
return request.request_id;
}
/**
* 同步推理(直接执行并返回结果)
*/
InferenceResult infer_sync(const InferenceRequest& request) {
auto it = backends_.find(request.task_type);
if (it == backends_.end()) {
InferenceResult result;
result.request_id = request.request_id;
result.success = false;
result.error_message = "不支持的任务类型";
return result;
}
return it->second->infer(request);
}
/**
* 关闭推理引擎
*/
void shutdown() {
running_ = false;
if (worker_thread_.joinable()) {
worker_thread_.join();
}
for (auto& [type, backend] : backends_) {
backend->unload();
}
}
/**
* 获取推理统计信息
*/
struct Stats {
long total_requests = 0;
long total_success = 0;
long total_failures = 0;
float avg_latency_ms = 0.0f;
float p99_latency_ms = 0.0f;
size_t queue_size = 0;
};
Stats get_stats() const {
Stats stats;
stats.total_requests = total_requests_.load();
stats.total_success = total_success_.load();
stats.total_failures = total_failures_.load();
stats.queue_size = task_queue_.size();
if (stats.total_success > 0) {
stats.avg_latency_ms = total_latency_ms_.load() / stats.total_success;
}
return stats;
}
private:
void detect_hardware() {
// 检测可用的硬件加速设备
// 瑞芯微NPU: 检查/dev/mali0或/dev/rknpu
// NVIDIA GPU: 检查CUDA Runtime
}
std::unique_ptr<InferenceBackend> create_backend(const std::string& model_name) {
// 根据设备类型创建对应的推理后端
if (device_ == DeviceType::GPU_CUDA) {
return std::make_unique<TensorRTBackend>();
}
return std::make_unique<OnnxRuntimeBackend>(device_);
}
std::string get_model_path(TaskType type) {
switch (type) {
case TaskType::OCR: return models_dir_ + "/ocr/model.onnx";
case TaskType::MATH_RECOGNITION: return models_dir_ + "/math/model.onnx";
case TaskType::STROKE_ORDER: return models_dir_ + "/stroke/model.onnx";
case TaskType::WRITING_QUALITY: return models_dir_ + "/quality/model.onnx";
}
return "";
}
/**
* 推理工作线程主循环
* 从任务队列取出请求,执行推理,存储结果
*/
void worker_loop() {
while (running_) {
InferenceRequest request;
if (task_queue_.dequeue(request, 100)) {
total_requests_++;
auto result = infer_sync(request);
if (result.success) {
total_success_++;
total_latency_ms_ += result.inference_time_ms;
} else {
total_failures_++;
}
// 存储结果供查询
std::lock_guard<std::mutex> lock(results_mutex_);
results_[request.request_id] = result;
}
}
}
DeviceType device_;
std::string models_dir_;
std::atomic<bool> running_;
std::thread worker_thread_;
InferenceTaskQueue task_queue_;
std::unordered_map<TaskType, std::unique_ptr<InferenceBackend>> backends_;
std::unordered_map<std::string, InferenceResult> results_;
std::mutex results_mutex_;
// 统计计数器
std::atomic<long> total_requests_{0};
std::atomic<long> total_success_{0};
std::atomic<long> total_failures_{0};
std::atomic<float> total_latency_ms_{0.0f};
};
#endif // INFERENCE_ENGINE_H
@@ -0,0 +1,443 @@
/**
* 自然写教室智能算力盒边缘计算软件 V1.0
* 模型管理模块 - 模型加载、版本管理、量化压缩、云端同步
*
* 管理算力盒上部署的所有AI推理模型的生命周期
* 支持模型热更新、A/B切换、云端版本同步
* 模型文件AES-256加密存储,推理时内存解密加载
*/
#ifndef MODEL_MANAGER_H
#define MODEL_MANAGER_H
#include <string>
#include <vector>
#include <memory>
#include <mutex>
#include <atomic>
#include <unordered_map>
#include <chrono>
#include <functional>
// ==================== 模型元信息 ====================
/** 模型状态枚举 */
enum class ModelState {
NOT_FOUND = 0, // 未发现
DOWNLOADING = 1, // 下载中
DECRYPTING = 2, // 解密中
LOADING = 3, // 加载到设备中
READY = 4, // 就绪可用
ACTIVE = 5, // 当前使用中
DEPRECATED = 6, // 已弃用
ERROR = 7 // 错误状态
};
/** 模型量化精度 */
enum class QuantizationType {
FP32 = 0, // 全精度浮点
FP16 = 1, // 半精度浮点
INT8 = 2, // 8位整型量化
INT4 = 3 // 4位整型量化(极致压缩)
};
/** 模型元信息 */
struct ModelInfo {
std::string name; // 模型名称
std::string version; // 版本号(语义化版本)
std::string format; // 格式(onnx/trt/rknn
std::string file_path; // 本地文件路径
size_t file_size_bytes; // 文件大小
std::string sha256; // 文件SHA-256校验和
QuantizationType quantization; // 量化类型
float accuracy; // 测试集准确率
float latency_ms; // 平均推理延迟
ModelState state; // 当前状态
std::string deployed_at; // 部署时间
std::string description; // 模型描述
};
// ==================== 模型加密管理 ====================
/**
* 模型文件加密/解密管理器
* 安全设计:模型文件AES-256加密存储,推理时内存解密加载
* 加密密钥通过安全芯片(TPM)或环境变量注入
*/
class ModelCryptoManager {
public:
ModelCryptoManager() : key_loaded_(false) {}
/**
* 加载加密密钥
* 优先从安全芯片读取,其次从环境变量
*/
bool load_encryption_key() {
// 尝试从TPM安全芯片读取密钥
// if (tpm_available()) { key_ = tpm_read_key("model_key"); }
// 后备方案:从环境变量读取
const char* env_key = std::getenv("WRITECH_MODEL_KEY");
if (env_key) {
key_ = std::string(env_key);
key_loaded_ = true;
return true;
}
return false;
}
/**
* 解密模型文件到内存
* 不在磁盘上生成明文文件,仅在内存中解密
*/
std::vector<uint8_t> decrypt_model(const std::string& encrypted_path) {
std::vector<uint8_t> decrypted_data;
if (!key_loaded_) return decrypted_data;
// 读取加密文件
// AES-256-CBC解密
// openssl EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
// EVP_DecryptUpdate(ctx, output, &out_len, input, in_len);
// EVP_DecryptFinal_ex(ctx, output + out_len, &final_len);
return decrypted_data;
}
/**
* 加密模型文件
* 新下载的模型文件加密后存储到本地Flash
*/
bool encrypt_model(const std::vector<uint8_t>& data, const std::string& output_path) {
if (!key_loaded_) return false;
// AES-256-CBC加密并写入文件
return true;
}
/**
* 验证模型文件完整性
* 计算SHA-256校验和并与元数据中的值比对
*/
bool verify_integrity(const std::string& file_path, const std::string& expected_sha256) {
// 计算文件SHA-256
// SHA256_CTX sha256;
// SHA256_Init(&sha256);
// while (read chunk) SHA256_Update(&sha256, chunk, len);
// SHA256_Final(hash, &sha256);
return true;
}
private:
std::string key_;
bool key_loaded_;
};
// ==================== 模型版本管理器 ====================
/**
* 模型版本管理器
* 管理算力盒上所有AI模型的版本、加载、切换
* 支持A/B分区切换实现热更新
*/
class ModelVersionManager {
public:
ModelVersionManager(const std::string& models_dir)
: models_dir_(models_dir) {}
/**
* 注册模型
* 扫描模型目录,加载所有可用模型的元信息
*/
bool register_model(const ModelInfo& info) {
std::lock_guard<std::mutex> lock(mutex_);
std::string key = info.name + "@" + info.version;
models_[key] = info;
return true;
}
/**
* 激活指定版本的模型
* 将旧版本标记为deprecated,新版本标记为active
*/
bool activate_version(const std::string& name, const std::string& version) {
std::lock_guard<std::mutex> lock(mutex_);
// 将当前活跃版本设为deprecated
for (auto& pair : models_) {
if (pair.second.name == name && pair.second.state == ModelState::ACTIVE) {
pair.second.state = ModelState::DEPRECATED;
}
}
// 激活新版本
std::string key = name + "@" + version;
auto it = models_.find(key);
if (it != models_.end()) {
it->second.state = ModelState::ACTIVE;
return true;
}
return false;
}
/**
* 获取当前活跃版本的模型信息
*/
ModelInfo get_active_model(const std::string& name) {
std::lock_guard<std::mutex> lock(mutex_);
for (const auto& pair : models_) {
if (pair.second.name == name && pair.second.state == ModelState::ACTIVE) {
return pair.second;
}
}
return ModelInfo{};
}
/**
* 获取所有模型状态列表
*/
std::vector<ModelInfo> get_all_models() {
std::lock_guard<std::mutex> lock(mutex_);
std::vector<ModelInfo> result;
for (const auto& pair : models_) {
result.push_back(pair.second);
}
return result;
}
/**
* 清理已废弃的旧版本模型文件
* 保留最近2个版本,删除更早的版本释放存储空间
*/
void cleanup_old_versions(const std::string& name, int keep_count = 2) {
std::lock_guard<std::mutex> lock(mutex_);
std::vector<std::string> deprecated_keys;
for (const auto& pair : models_) {
if (pair.second.name == name && pair.second.state == ModelState::DEPRECATED) {
deprecated_keys.push_back(pair.first);
}
}
// 按版本排序,保留最新的keep_count个
if (static_cast<int>(deprecated_keys.size()) > keep_count) {
for (int i = 0; i < static_cast<int>(deprecated_keys.size()) - keep_count; i++) {
// 删除模型文件并从注册表移除
models_.erase(deprecated_keys[i]);
}
}
}
private:
std::string models_dir_;
std::unordered_map<std::string, ModelInfo> models_;
std::mutex mutex_;
};
// ==================== 云端模型同步器 ====================
/**
* 云端模型同步器
* 定期检查云端是否有新版本模型,自动下载并部署
* 通过HTTPS加密通道下载,下载后RSA签名校验
*/
class CloudModelSyncer {
public:
CloudModelSyncer(const std::string& server_url, const std::string& device_id)
: server_url_(server_url), device_id_(device_id) {}
/**
* 检查云端是否有模型更新
* GET /api/v1/model/check-update?device_id=xxx&models=ocr@1.0,math@1.0
*/
struct UpdateInfo {
std::string model_name;
std::string new_version;
std::string download_url;
size_t file_size;
std::string sha256;
};
std::vector<UpdateInfo> check_updates(const std::vector<ModelInfo>& current_models) {
std::vector<UpdateInfo> updates;
// 向云端API发送当前模型版本列表,获取可更新版本
// HTTPS请求:GET server_url_/api/v1/model/check-update
return updates;
}
/**
* 下载模型文件
* HTTPS下载,支持断点续传
* 下载完成后进行SHA-256校验和RSA签名验证
*/
bool download_model(const UpdateInfo& info, const std::string& save_path) {
// HTTPS下载
// 进度回调上报
// SHA-256校验
// RSA签名验证(OTA安全:升级包RSA签名+SHA-256校验,防篡改)
return true;
}
/**
* 上报模型部署状态
* POST /api/v1/model/deploy-status
*/
void report_deploy_status(const std::string& model_name, const std::string& version,
bool success, const std::string& error = "") {
// 向云端上报模型部署结果
}
private:
std::string server_url_;
std::string device_id_;
};
// ==================== OTA固件升级管理器 ====================
/**
* OTA固件升级管理器
* 管理算力盒固件的远程升级
* 采用A/B双分区方案,升级失败自动回滚
* 安全设计:升级包RSA签名+SHA-256校验,防篡改
*/
class OtaUpgradeManager {
public:
enum class OtaState {
IDLE, // 空闲
CHECKING, // 检查更新中
DOWNLOADING, // 下载中
VERIFYING, // 校验中
INSTALLING, // 安装中
REBOOTING, // 重启中
FAILED // 失败
};
OtaUpgradeManager(const std::string& ota_url, const std::string& device_id)
: ota_url_(ota_url), device_id_(device_id), state_(OtaState::IDLE),
current_partition_("A"), download_progress_(0) {}
/** 检查固件更新 */
bool check_update() {
state_ = OtaState::CHECKING;
// GET ota_url_/api/v1/ota/check?device_id=xxx&version=xxx
return false; // 返回是否有新版本
}
/** 下载固件升级包 */
bool download_firmware(const std::string& download_url) {
state_ = OtaState::DOWNLOADING;
// HTTPS分块下载到非活跃分区
// 支持断点续传
return true;
}
/** 验证固件包完整性和签名 */
bool verify_firmware(const std::string& firmware_path) {
state_ = OtaState::VERIFYING;
// SHA-256校验
// RSA-2048签名验证
return true;
}
/** 安装固件(写入非活跃分区) */
bool install_firmware() {
state_ = OtaState::INSTALLING;
// 写入B分区(如当前运行A分区)
// 设置下次启动从B分区引导
return true;
}
/** 回滚到上一版本 */
bool rollback() {
// 切换回上一个分区
std::string target = (current_partition_ == "A") ? "B" : "A";
// 设置引导分区为target
return true;
}
/** 获取当前OTA状态 */
OtaState get_state() const { return state_; }
int get_progress() const { return download_progress_; }
std::string get_current_partition() const { return current_partition_; }
private:
std::string ota_url_;
std::string device_id_;
OtaState state_;
std::string current_partition_;
int download_progress_;
};
// ==================== 系统监控模块 ====================
/**
* 系统运行状态监控
* 采集CPU、内存、GPU/NPU利用率、温度等硬件指标
* 为云端监控告警和集群调度提供数据支撑
*/
class SystemMonitor {
public:
struct SystemMetrics {
float cpu_usage_percent; // CPU使用率
float memory_usage_percent; // 内存使用率
long memory_total_mb; // 总内存
long memory_used_mb; // 已用内存
float gpu_usage_percent; // GPU/NPU利用率
float gpu_memory_usage_mb; // GPU显存使用
float gpu_temperature_c; // GPU温度
float disk_usage_percent; // 磁盘使用率
float network_rx_mbps; // 网络接收速率
float network_tx_mbps; // 网络发送速率
long uptime_seconds; // 系统运行时长
};
SystemMonitor() : running_(false) {}
/** 启动监控采集线程 */
void start(int interval_ms = 5000) {
running_ = true;
// 定时采集系统指标
}
/** 获取最新系统指标 */
SystemMetrics get_metrics() {
SystemMetrics metrics;
metrics.cpu_usage_percent = read_cpu_usage();
metrics.memory_usage_percent = read_memory_usage();
metrics.gpu_usage_percent = read_gpu_usage();
metrics.gpu_temperature_c = read_gpu_temperature();
metrics.disk_usage_percent = read_disk_usage();
return metrics;
}
void stop() { running_ = false; }
private:
float read_cpu_usage() {
// 读取 /proc/stat 计算CPU使用率
return 0.0f;
}
float read_memory_usage() {
// 读取 /proc/meminfo
return 0.0f;
}
float read_gpu_usage() {
// NVIDIA: nvidia-smi / NVML
// 瑞芯微: /sys/class/devfreq/xxx
return 0.0f;
}
float read_gpu_temperature() {
// 读取GPU温度传感器
return 0.0f;
}
float read_disk_usage() {
// statfs("/")
return 0.0f;
}
std::atomic<bool> running_;
};
#endif // MODEL_MANAGER_H
@@ -0,0 +1,431 @@
/**
* 自然写教室智能算力盒边缘计算软件 V1.0
* NPU/GPU硬件调度模块 - 硬件加速资源管理与任务分配
*
* 管理算力盒上的NPU/GPU计算资源
* 支持多种硬件平台:NVIDIA GPU(CUDA)、瑞芯微NPU(RKNN)、通用GPU(OpenCL)
* 根据任务类型和硬件负载动态选择最优推理路径
*/
#ifndef NPU_SCHEDULER_H
#define NPU_SCHEDULER_H
#include <string>
#include <vector>
#include <memory>
#include <mutex>
#include <atomic>
#include <chrono>
#include <queue>
#include <functional>
#include <unordered_map>
#include <thread>
#include <condition_variable>
#include <cstring>
// ==================== 硬件设备抽象 ====================
/** 硬件加速器类型 */
enum class AcceleratorType {
CPU_ONLY = 0, // 仅CPU(无加速器可用时的兜底方案)
NVIDIA_GPU = 1, // NVIDIA GPU (CUDA/TensorRT)
ROCKCHIP_NPU = 2, // 瑞芯微NPU (RKNN)
AMLOGIC_NPU = 3, // 晶晨NPU
GENERIC_OPENCL = 4 // 通用OpenCL GPU
};
/** 硬件设备信息 */
struct AcceleratorDevice {
AcceleratorType type; // 加速器类型
int device_id; // 设备编号
std::string name; // 设备名称
std::string driver_version; // 驱动版本
size_t total_memory_mb; // 总显存/内存(MB)
size_t free_memory_mb; // 可用显存/内存(MB)
float compute_capability; // 算力指标
float current_utilization; // 当前利用率(0-1)
float temperature_celsius; // 当前温度
float max_temperature; // 最高安全温度
bool is_available; // 是否可用
};
/** 推理任务资源需求 */
struct TaskResourceRequirement {
size_t memory_mb; // 需要的显存(MB)
float estimated_time_ms; // 预估推理时间
bool requires_fp16; // 是否需要FP16支持
bool requires_int8; // 是否需要INT8支持
int preferred_device; // 偏好设备ID-1表示无偏好)
};
// ==================== 硬件检测器 ====================
/**
* 硬件加速器检测器
* 启动时扫描系统中可用的NPU/GPU设备
* 自动匹配设备驱动和推理后端
*/
class HardwareDetector {
public:
/**
* 扫描系统中所有可用的加速器设备
* 检测顺序:NVIDIA GPU → 瑞芯微NPU → 通用OpenCL → CPU
*/
std::vector<AcceleratorDevice> detect_devices() {
std::vector<AcceleratorDevice> devices;
// 检测NVIDIA GPU
if (detect_nvidia_gpu(devices)) {
// 通过NVML库获取GPU信息
}
// 检测瑞芯微NPU
if (detect_rockchip_npu(devices)) {
// 通过sysfs获取NPU信息
}
// 如果没有加速器,添加CPU作为兜底
if (devices.empty()) {
AcceleratorDevice cpu_dev;
cpu_dev.type = AcceleratorType::CPU_ONLY;
cpu_dev.device_id = 0;
cpu_dev.name = "CPU";
cpu_dev.total_memory_mb = get_system_memory_mb();
cpu_dev.free_memory_mb = get_free_memory_mb();
cpu_dev.is_available = true;
devices.push_back(cpu_dev);
}
return devices;
}
private:
bool detect_nvidia_gpu(std::vector<AcceleratorDevice>& devices) {
// 检查 /dev/nvidia0 是否存在
// 使用NVML API获取设备信息
// nvmlInit();
// nvmlDeviceGetCount(&count);
// for (int i = 0; i < count; i++) {
// nvmlDeviceGetHandleByIndex(i, &device);
// nvmlDeviceGetName(device, name, sizeof(name));
// nvmlDeviceGetMemoryInfo(device, &mem);
// nvmlDeviceGetUtilizationRates(device, &util);
// nvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &temp);
// }
return false;
}
bool detect_rockchip_npu(std::vector<AcceleratorDevice>& devices) {
// 检查 /dev/rknpu 或 /sys/class/misc/rknpu 是否存在
// 读取NPU硬件信息
// cat /sys/kernel/debug/rknpu/load // NPU负载
return false;
}
size_t get_system_memory_mb() {
// 读取 /proc/meminfo
return 4096; // 默认4GB
}
size_t get_free_memory_mb() {
return 2048;
}
};
// ==================== 设备负载监控 ====================
/**
* 硬件设备负载实时监控
* 定期采集GPU/NPU利用率、温度、显存使用等指标
* 为调度策略提供实时数据支撑
*/
class DeviceLoadMonitor {
public:
struct DeviceMetrics {
int device_id;
float utilization; // 利用率 (0-1)
float memory_usage; // 显存使用率 (0-1)
float temperature; // 温度(摄氏度)
float power_watts; // 功耗(瓦)
int inference_qps; // 当前推理QPS
std::chrono::steady_clock::time_point timestamp;
};
DeviceLoadMonitor() : running_(false) {}
/** 启动监控(后台线程定期采集) */
void start(int interval_ms = 1000) {
running_ = true;
monitor_thread_ = std::thread([this, interval_ms]() {
while (running_) {
collect_metrics();
std::this_thread::sleep_for(std::chrono::milliseconds(interval_ms));
}
});
}
/** 获取指定设备的最新指标 */
DeviceMetrics get_metrics(int device_id) {
std::lock_guard<std::mutex> lock(mutex_);
auto it = latest_metrics_.find(device_id);
if (it != latest_metrics_.end()) {
return it->second;
}
return DeviceMetrics{};
}
/** 获取所有设备指标 */
std::vector<DeviceMetrics> get_all_metrics() {
std::lock_guard<std::mutex> lock(mutex_);
std::vector<DeviceMetrics> result;
for (const auto& pair : latest_metrics_) {
result.push_back(pair.second);
}
return result;
}
void stop() {
running_ = false;
if (monitor_thread_.joinable()) {
monitor_thread_.join();
}
}
private:
void collect_metrics() {
std::lock_guard<std::mutex> lock(mutex_);
// NVIDIA GPU: nvmlDeviceGetUtilizationRates + nvmlDeviceGetTemperature
// 瑞芯微NPU: 读取 /sys/kernel/debug/rknpu/load
// CPU: 读取 /proc/stat
}
std::unordered_map<int, DeviceMetrics> latest_metrics_;
std::mutex mutex_;
std::atomic<bool> running_;
std::thread monitor_thread_;
};
// ==================== 调度策略 ====================
/**
* 推理任务调度策略
* 根据任务特征和设备负载选择最优的推理设备
*/
class SchedulingPolicy {
public:
virtual ~SchedulingPolicy() = default;
/** 选择最优设备执行推理任务 */
virtual int select_device(const TaskResourceRequirement& requirement,
const std::vector<AcceleratorDevice>& devices,
const std::vector<DeviceLoadMonitor::DeviceMetrics>& metrics) = 0;
};
/**
* 最小负载调度策略
* 优先选择当前利用率最低的设备
*/
class MinLoadPolicy : public SchedulingPolicy {
public:
int select_device(const TaskResourceRequirement& requirement,
const std::vector<AcceleratorDevice>& devices,
const std::vector<DeviceLoadMonitor::DeviceMetrics>& metrics) override {
int best_device = 0;
float min_load = 1.0f;
for (size_t i = 0; i < devices.size(); i++) {
if (!devices[i].is_available) continue;
if (devices[i].free_memory_mb < requirement.memory_mb) continue;
float load = (i < metrics.size()) ? metrics[i].utilization : 0.0f;
if (load < min_load) {
min_load = load;
best_device = static_cast<int>(i);
}
}
return best_device;
}
};
/**
* 温度感知调度策略
* 除了负载外还考虑设备温度,防止过热降频
*/
class ThermalAwarePolicy : public SchedulingPolicy {
public:
ThermalAwarePolicy(float temp_threshold = 80.0f) : temp_threshold_(temp_threshold) {}
int select_device(const TaskResourceRequirement& requirement,
const std::vector<AcceleratorDevice>& devices,
const std::vector<DeviceLoadMonitor::DeviceMetrics>& metrics) override {
int best_device = 0;
float best_score = -1.0f;
for (size_t i = 0; i < devices.size(); i++) {
if (!devices[i].is_available) continue;
if (devices[i].free_memory_mb < requirement.memory_mb) continue;
float load = (i < metrics.size()) ? metrics[i].utilization : 0.0f;
float temp = (i < metrics.size()) ? metrics[i].temperature : 0.0f;
// 综合评分:负载权重0.6 + 温度权重0.4
float load_score = 1.0f - load;
float temp_score = (temp < temp_threshold_) ? 1.0f : (1.0f - (temp - temp_threshold_) / 20.0f);
float score = load_score * 0.6f + temp_score * 0.4f;
if (score > best_score) {
best_score = score;
best_device = static_cast<int>(i);
}
}
return best_device;
}
private:
float temp_threshold_;
};
// ==================== NPU调度器(核心) ====================
/**
* NPU/GPU硬件调度器
* 管理推理任务到硬件设备的分配调度
* 核心功能:
* 1. 硬件资源池化管理
* 2. 基于负载和温度的智能调度
* 3. 设备故障自动切换
* 4. 推理性能指标采集
*/
class NpuScheduler {
public:
NpuScheduler() : initialized_(false) {}
/**
* 初始化调度器
* 检测硬件设备,启动负载监控,设置调度策略
*/
bool initialize() {
// 检测可用硬件加速器
HardwareDetector detector;
devices_ = detector.detect_devices();
if (devices_.empty()) {
return false;
}
// 启动设备负载监控
load_monitor_.start(1000);
// 设置调度策略(默认温度感知策略)
policy_ = std::make_unique<ThermalAwarePolicy>(80.0f);
initialized_ = true;
return true;
}
/**
* 为推理任务分配最优设备
*/
int schedule_task(const TaskResourceRequirement& requirement) {
if (!initialized_) return 0;
auto metrics = load_monitor_.get_all_metrics();
return policy_->select_device(requirement, devices_, metrics);
}
/**
* 获取所有设备状态
*/
std::vector<AcceleratorDevice> get_device_status() {
// 更新设备实时状态
auto metrics = load_monitor_.get_all_metrics();
for (auto& dev : devices_) {
for (const auto& m : metrics) {
if (m.device_id == dev.device_id) {
dev.current_utilization = m.utilization;
dev.temperature_celsius = m.temperature;
}
}
}
return devices_;
}
/** 获取调度统计信息 */
struct SchedulerStats {
long total_tasks_scheduled;
long total_tasks_completed;
long total_tasks_failed;
float avg_inference_ms;
float gpu_avg_utilization;
float gpu_temperature;
int active_devices;
};
SchedulerStats get_stats() {
SchedulerStats stats;
stats.total_tasks_scheduled = tasks_scheduled_.load();
stats.total_tasks_completed = tasks_completed_.load();
stats.total_tasks_failed = tasks_failed_.load();
stats.active_devices = static_cast<int>(devices_.size());
auto metrics = load_monitor_.get_all_metrics();
if (!metrics.empty()) {
float total_util = 0;
for (const auto& m : metrics) total_util += m.utilization;
stats.gpu_avg_utilization = total_util / metrics.size();
stats.gpu_temperature = metrics[0].temperature;
}
return stats;
}
void shutdown() {
load_monitor_.stop();
initialized_ = false;
}
private:
std::vector<AcceleratorDevice> devices_;
DeviceLoadMonitor load_monitor_;
std::unique_ptr<SchedulingPolicy> policy_;
bool initialized_;
std::atomic<long> tasks_scheduled_{0};
std::atomic<long> tasks_completed_{0};
std::atomic<long> tasks_failed_{0};
};
// ==================== 配置管理 ====================
/**
* 算力盒配置管理(边缘设备专用)
* 从JSON配置文件和环境变量加载配置
* 支持运行时配置热更新(通过MQTT远程指令)
*/
struct EdgeBoxConfiguration {
// 推理配置
int max_concurrent_inferences = 4; // 最大并发推理数
int inference_queue_size = 256; // 推理队列大小
int default_timeout_ms = 500; // 默认推理超时
// NPU/GPU配置
float gpu_memory_fraction = 0.8f; // GPU显存使用比例上限
float thermal_throttle_temp = 80.0f; // 温度降频阈值
bool enable_fp16 = true; // 启用FP16推理
bool enable_int8 = false; // 启用INT8量化
// 网络配置
std::string grpc_listen = "0.0.0.0:50052";
std::string mqtt_broker = "ssl://mqtt.writech.com:8883";
bool enable_mtls = true;
// 存储配置
std::string models_dir = "/opt/models";
std::string cache_dir = "/var/lib/writech/cache";
int offline_cache_max_mb = 256;
// 集群配置
bool enable_cluster = true;
std::string cluster_discovery = "mdns";
};
#endif // NPU_SCHEDULER_H