目录
CodeProject.AI Server是一个基于HTTP的REST API服务器,旨在通过隐藏复杂性并为作为CodeProject.AI系统的一部分安装的每个AI模块提供简单的API来简化向现有系统或应用程序添加AI功能的过程。
介绍
如果您乐于遵循曲折的迷宫,那么将AI功能添加到应用程序中是相当简单的,这是无穷无尽的库、工具、解释器、包管理器和所有其他有趣的东西,有时让编码变得像洗碗一样有趣。
我们构建了 CodeProject.AI Server 来隐藏开发人员的所有烦人的事情,并给他们留下一个简单的AI包,该包可以做一些事情,并且易于与现有应用程序一起使用。
如果CodeProject.AI Server不能满足您的需求,那么很容易添加可以填补空白的模块。
聚合,而不是添加
我们说“添加”,但“聚合”更准确。有大量令人惊叹的AI项目正在积极开发和改进,我们希望允许开发人员将这些现有的、不断发展的AI模块或应用程序放入CodeProject.AI生态系统中,尽可能少地大惊小怪。这可能意味着放入控制台应用程序、Python模块或.NET项目。
对于开发,您需要做的就是
- 创建一个安装脚本(通常很短)来设置先决条件(下载模型、安装必要的库、创建一些文件夹(如果需要)
- 编写一个适配器来处理模块和 CodeProject.AI 服务器之间的通信,
- 提供描述模块的modulesettings.json文件,并向 CodeProject.AI 提供有关如何启动模块的说明。
在30秒内完成CodeProject.AI服务器架构
CodeProject.AI Server是基于HTTP的REST API服务器。它基本上只是一个Web服务器,您的应用程序向其发送请求。这些请求被放置在一个队列中,分析服务(又名模块)从它们知道如何处理的队列中挑选请求。然后处理每个请求(根据请求执行AI操作),并将结果发送回API服务器,API服务器又将其发送回进行初始调用的应用程序。
将CodeProject.AI Server想象成数据库服务器或您在后台运行的任何其他服务:它作为服务或守护程序运行,您向它发送命令,它就会响应结果。您无需担心它如何开展业务的细节,您只需专注于应用程序的核心业务。
CodeProject.AI Server API服务器独立于调用应用程序运行。
例如,假设我们有三个分析模块,使用Python 3.7的人脸识别、使用.NET的对象检测和使用Python 3.10的文本分析:
- 应用程序向API服务器发送请求
- API服务器将请求放在相应的队列上
- 后端模块轮询他们感兴趣的队列,抓取请求并对其进行处理
- 然后,后端模块将结果发送回API服务器
- 然后,API服务器将结果发送回调用应用程序
每个后端模块都可以在任何技术堆栈上运行,并在安装的任何运行时下运行——Python,.NET,Go,C++——任何可以在主机系统上运行的运行。由模块的安装程序来确保主机系统安装了所需的任何部件,但CodeProject.AI Server为此提供了很多帮助。
向CodeProject.AI服务器添加新模块
添加新模块有三个任务:
- 创建一个设置文件,指示服务器和安装程序需要什么模块
- 确保通过安装脚本正确安装任何先决条件,例如模型、库或解释器
- 编写实际模块并将其连接到CodeProject.AI服务器
设置文件
这是一个简单的JSON文件,提供常规信息,例如模块的名称、版本和描述,以及使用的运行时、版本兼容性信息、GPU使用指南和路由信息。路由信息允许服务器侦听给定的API路由,并将这些请求传递给模块。
安装脚本
安装脚本(和安装后脚本)提供了下载模型、安装运行时、构建和安装库以及执行确保模块可以运行所需的任何任务的机会。您将需要一个用于Windows安装程序的Windows BAT文件,以及一个用于Linux/macOS安装程序的bash文件。
最新版本的CodeProject.AI服务器不需要安装脚本来安装Python或.NET——这些脚本由核心安装系统根据您的设置文件进行处理。如果安装系统看到模块使用的是.NET或Python,它将设置这些环境,对于Python,它还将查找需求文件中的包并将其安装到虚拟环境中。
其他运行时或支持服务应由安装脚本添加。
编写模块
编写模块是有趣的部分。事实上,你通常不需要编写一个新模块:有数百个优秀的开源、独立的人工智能项目可以制作出优秀的模块。您需要做的就是确保模块可以在已安装的环境中运行(在先决条件步骤中处理),下载它需要的任何模型并放在正确的位置(同样,应该已经完成),并且模块可以与CodeProject.AI服务器通信。
我们将为多种语言提供一个简单的SDK,这将有助于您编写适合模块和CodeProject.AI Server之间的填充码并负责通信。
让我们添加一个模块
我们将添加rembg模块。这是一个简单但有趣的AI模块,可以拍摄任何包含主题的照片并从图像中删除背景。它在Python 3.9或更高版本下运行。
安装程序
该rembg模块包括以下内容:
- Python代码
- Python 3.9解释器
- 一些Python包
- 人工智能模型
为了确保这些在开发环境中都到位,我们需要修改 /Installers/Dev 中的安装脚本。
适用于Windows(install.bat)
:: Background Remover :::::::::::::::::::::::::::::::::::::::::::::::::::::::::
call "%sdkScriptsDirPath%\utils.bat" GetFromServer "rembg-models.zip" "models" "Downloading Background Remover models..."
这并不简单:它只是从CodeProject S3存储桶下载模型并将文件移动到适当的位置。该GetFromServer函数包含在SDK脚本中,并采用文件名、要将文件提取到的文件夹名称(相对于当前模块)和一条消息
适用于Linux或macOS
该脚本与Windows版本基本相同:
# Background Remover :::::::::::::::::::::::::::::::::::::::::::::::::::::::::
getFromServer "rembg-models.zip" "models" "Downloading Background Remover models..."
模块的API
我们应该从如何调用模块开始。它可以是任何我们喜欢的东西,所以让我们选择路由/v1/image/removebackground。我们将传入一个图像和一个布尔值use_alphamatting,它告诉代码是否使用alpha抠图(更适合模糊边缘)。
返回包将包括一个项imageBase64,其中包含删除了背景的图像的base64编码版本。
模块的源代码
首先,我们在modules目录下创建一个文件夹,并复制该模块的代码。在本例中,我们会将代码存储在/src/modules/BackgroundRemover中。为方便起见,我们将为使用Visual Studio的用户创建一个Python项目(在VS Code中工作同样简单)。
该rembg模块有一个我们需要调用的主要方法,名为remove。我们需要能够从客户端的请求中获取数据到此方法,然后将此方法的结果传递回客户端。为此,我们将使用src/SDK/Python/module_runner.py模块来提供帮助。
我们还将为rembg创建一个适配器(我们称之为 rembg_adapter.py),它将rembg remove方法与我们的codeprojectAI.py帮助程序模块连接起来。
# Import our general libraries
import sys
import time
# Import the CodeProject.AI SDK. This will add to the PATH var for
# future imports
sys.path.append("../../SDK/Python")
from request_data import RequestData
from module_runner import ModuleRunner
from common import JSON
# Import the method of the module we're wrapping
from PIL import Image
# Import the method of the module we're wrapping
from rembg.bg import remove
class rembg_adapter(ModuleRunner):
def initialise(self) -> None:
""" Initialises the module """
pass
def process(self, data: RequestData) -> JSON:
""" Processes a request from the client and returns the results"""
try:
img: Image = data.get_image(0)
use_alphamatting: bool = data.get_value("use_alphamatting", "false") == "true"
# Make the call to the AI code we're wrapping, and time it
start_time = time.perf_counter()
(processed_img, inferenceTime) = remove(img, use_alphamatting)
processMs = int((time.perf_counter() - start_time) * 1000)
return {
"success": True,
"imageBase64": RequestData.encode_image(processed_img),
"processMs" : processMs,
"inferenceMs" : inferenceTime
}
except Exception as ex:
self.report_error(ex, __file__)
return {"success": False, "error": "unable to process the image"}
def shutdown(self) -> None:
pass
if __name__ == "__main__":
rembg_adapter().start_loop()
这是我们添加的唯一代码。该rembg模块已按原样复制和粘贴,我们正在重用 ModuleRunner 工作类。不需要添加任何其他(代码方面)。
modulesettings.json文件
此文件位于 BackgroundRemover 文件夹中,指示API服务器如何启动新的分析服务。
{
"Modules": {
"BackgroundRemoval": {
"Name": "Background Remover",
"Version": "1.6.2",
// Publishing info
"Description": "Automatically removes the background from a picture",
"Platforms": [ "windows", /*"linux",*/ "linux-arm64", "macos", "macos-arm64" ], // issues with numpy on linux
"License": "SSPL",
"LicenseUrl": "https://www.mongodb.com/licensing/server-side-public-license",
// Launch instructions
"AutoStart": false,
"FilePath": "rembg_adapter.py",
"Runtime": "python3.9",
"RuntimeLocation": "Local", // Can be Local or Shared
"EnvironmentVariables": {
"U2NET_HOME": "%CURRENT_MODULE_PATH%/models" // where to store the models
},
"RouteMaps": [
// ... (explained below)
]
}
}
}
该EnvironmentVariables部分定义了键/值对,这些键/值对将用于设置模块可能需要的环境变量。在本例中,是AI模型文件的路径。这是特定于rembg模块并由其定义的值。
CURRENT_MODULES_PATH是一个宏,它将扩展到包含模块的目录的位置。在本例中为/src/AnalysisLayer。
FilePath是要执行的文件的路径,相对于当前模块的目录。
AutoStart设置是否在服务器启动时启动此模块。
运行时定义将启动文件的运行时。我们目前支持dotnet(.NET)、python3.6到Python 3.12,或者只是python如果您将使用Python的系统默认版本。如果省略,CodeProject.AI Server将尝试根据FilePath进行猜测。
该Platforms数组包含服务可以运行的每个平台的条目。目前支持Windows、Linux、macOS和Docker。
该文件还定义了该RouteMaps部分下模块的API路由
{
"Modules": {
"ModulesConfig": {
"BackgroundRemoval": {
"Name": "Background Removal",
"Description": "Removes backgrounds from images.",
...
"RouteMaps": [
{
"Path": "image/removebackground",
"Command": "removebackground",
"Description": "Removes the background from images.",
"Inputs": [ ... ],
"Outputs": [...]
}
]
}
}
}
}
Path是API路径,在本例中为 localhost:5000/v1/image/removebackground。请记住,这是我们(任意)选择的API 。它可以是任何东西,只要它当前未被使用。
Command是API控制器中将要调用的方法,在本例中为removebackground。 Queue是API服务器中将管理此服务请求的队列的名称。
在我们编写的适配器Python模块中,我们有这样的代码:
QUEUE_NAME = "removebackground_queue"
Queue,在路由映射中,应与此名称匹配。
Description,Inputs和Outputs是现阶段的纯文档。
将调用我们的新模块的客户端
可以使用简单的JavaScript测试工具来演示新模块。
// Assume we have a HTML INPUT type=file control with ID=fileChooser
var formData = new FormData();
formData.append('image', fileChooser.files[0]);
formData.append("use_alphamatting", 'false');
var url = 'http://localhost:5000/v1/image/removebackground';
fetch(url, { method: "POST", body: formData})
.then(response => {
if (response.ok) {
response.json().then(data => {
// img is an IMG tag that will display the result
img.src = "data:image/png;base64," + data.imageBase64;
})
}
})
该项目包含实现此功能的文件test.html,提供用于收集信息和显示结果的UI。
安装和测试
此时,我们有一个模块、一个安装脚本和一个测试客户端。让我们试一试。
- 确保已下载最新的 CodeProject.AI Server存储库。这已经包含了我们上面讨论的所有代码。
- 在/src中运行安装脚本。这将确保安装和设置Python 3.9,并安装所需的Python模块。
- 通过在Visual Studio或VS Code中启动新的调试会话来启动服务器。
- 在调试中,CodeProject.AI Server仪表板在运行时自动启动。服务器启动后,仪表板将显示所有后端模块的状态,包括我们刚刚添加的后台删除模块。请注意,在下图中,出于演示目的,我们故意禁用了一些模块的启动。
- 在浏览器中启动index.html文件,选择一个文件,然后单击“提交”按钮。应显示结果。
下一步是什么?
这取决于你。我们演示了一个非常简单的AI模块,它可以去除图像中的背景。主要工作是
- 确保您在服务器上有可用的资产(例如模型),以便可以下载它们
- 更新安装脚本,以便可以下载资产并将其移动到位,并确保安装了必要的运行时和库
- 放入模块的代码并编写适配器,以便它可以与CodeProject.AI Server通信
- 编写描述模块API的modulesettings文件
- 测试!永远是有趣的部分。
您可以添加的可能性几乎是无限的。我们的目标是使您作为开发人员能够轻松添加自己的AI模块,从而获得其他人添加的模块的好处。混合搭配,使用不同的训练模块集,尝试设置,看看你可以在哪里使用它。
这是关于学习的,也是关于玩得开心的。去吧。
下一篇https://www.codeproject.com/Articles/5332075/Adding-a-New-Module-to-CodeProject-AI-Server