运用AI搭建中间服务层(五)

news2025/4/25 23:55:16

其他文件的修改

ValuesControllers.cs 注意Post的参数从[FromBody]变成了[FromForm],以便接收上传的图片流数据

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using CognitiveMiddlewareService.CognitiveServices;
using CognitiveMiddlewareService.Processors;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;

namespace CognitiveMiddlewareService.Controllers
{
    [Route("api/[controller]")]
    public class ValuesController : Controller
    {
        private readonly IProcessService processor;

        public ValuesController(IProcessService ps)
        {
            this.processor = ps;
        }

        // GET api/values
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/values/5
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return "value";
        }

        // POST api/values
        [HttpPost]
        public async Task<string> Post([FromForm] IFormCollection formCollection)
        {
            try
            {
                IFormCollection form = await this.Request.ReadFormAsync();
                IFormFile file = form.Files.First();

                var bufferData = Helper.GetBuffer(file);
                var result = await this.processor.Process(bufferData);
                string jsonResult = JsonConvert.SerializeObject(result);
                // return json formatted data
                return jsonResult;
            }
            catch (Exception ex)
            {
                Debug.Write(ex.Message);
                return null;
            }
        }
    }
}

启动.cs

using CognitiveMiddlewareService.CognitiveServices;
using CognitiveMiddlewareService.MiddlewareService;
using CognitiveMiddlewareService.Processors;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace CognitiveMiddleService
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
            services.AddScoped<IProcessService, ProcessService>();
            services.AddScoped<IVisionService, VisionService>();
            services.AddScoped<ILandmarkService, LandmarkService>();
            services.AddScoped<ICelebrityService, CelebrityService>();
            services.AddScoped<IEntitySearchService, EntitySearchService>();
            services.AddHttpClient();

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseMvc();
        }
    }
}

除了第一行的services.AddMvc()以外,后面所有的行都是我们需要增加的依赖注入代码。

层次关系总结

总结一下,从调用关系上看,是这个次序:

控制器 -> ProcessService -> LandmarkService/CelebrityService -> VisionService/EntitySearchService

其中:

  • Controller是个Endpoint

  • ProcessService负责任务调度

  • LandmarkService/CelebrityService是个集成服务,封装了串行调用底层服务的逻辑

  • VisionService/EntitySearchService是基础服务,相当于最底层的原子操作

从数据结构上看,进化的顺序是这样的:

VisionResult/EntityResult -> CelebrityResult/LandmarkResult -> 聚合结果

其中:

  • VisionResult/EntityResult是最底层返回的原始结果,主要用于反序列化

  • CelebrityResult/LandmarkResult是集成了多个原始结果后的抽象结果,好处是隔离了原始结果中的一些噪音,解耦,只返回我们需要的字段

  • AggregatedResult是聚合在一起的结果,主要用于排序和生成返回JSON数据

完整的中间服务层系统堆栈

有的人会问了:有必要搞这么复杂吗?这几个调用在一个帮助函数里不就可以搞定了吗?

确实是这样,如果不考虑应用扩展什么的,那就用一个帮助函数搞定;如果想玩儿点大的,那么下面这张图就是一个完整系统的Stack图,这个系统通过组合调用多种微软认知服务/微软地图服务/微软实体服务等,能够提供给用户的智能设备丰富的视觉对象识别体验。

上图包含了以下层次:

  • 端点

    • 两个Endpoint,一个处理图片输入,另一个处理文本输入
  • 处理和分类器

    • 包含图像/文字的预处理/预分类
  • 任务分派器

    • 并行调用多种服务并协调同步关系
  • API 代理和识别器

    • 组合调用各种API,内置的识别器(比如正则表达式)
  • 蜜蜂属

    • 各种认知服务API
  • 处理器

    • 隔离层/聚合层/排序器的组合称呼
  • 自适应卡片生成器

    • 生成微软最新推出的Adaptive Card技术的数据,供跨平台客户端接收并渲染
  • 助理 元件

    • 其它辅助组件

对中间服务层的测试

基本概念与环境搭建

做好了一个中间层服务,不是说简单地向Azure上一部署就算完事儿了。任何一个商用的软件,都需要严格的测试,对于普通的手机/客户端软件的测试,相信很多人都知道,覆盖功能点,各种条件输入,等等等等。对于中间层服务,除了功能点外,性能方面的测试尤其重要。

如何进行测试呢?

ASP.NET Core Web API有一套测试工具,请看这个链接:https://docs.microsoft.com/en-us/aspnet/core/test/?view=aspnetcore-2.1,它讲述了一些列的方法,我们不再赘述,本文所要描述的是三种面向场景的测试方法:负载(较重的压力)测试,(较轻的压力)性能测试,(中等的压力)稳定性测试。不是以show code为主,而是以讲理念为主,懂得了理念,code容易写啦。

对于一个普通的App,我们用界面交互的方式进行测试。对于一个service,它的界面就相当于REST API,我们可以从客户端发起测试,自动化程度较高。

在Visual Studio 2017,有专门的Load Test工具可以帮助我们完成在客户端编写测试代码,调整各种测试参数,然后发起测试,具体的链接在这里。

在本文中,我们主要从概念上讲解一下针对含有认知服务的中间服务层的测试方法,因为认知服务本身如果访问量大的话,是要收取费用的!

小提示:各个认知服务的费用标准不同,请仔细阅读相关网页,以免在进行大量的测试时引起不必要的费用发生。

负载测试 Load Test

测试目的

模拟多个并发用户访问中间层服务,集中发生在一个持续的时间段内,以衡量服务质量。负载测试不断的发展下去,负载越来越大,就会变成极限测试,最终把机器跑瘫为止。

测试环境

注意!我们不是在测试认知服务的性能,是要测试自己的中间层服务的性能,所以如下图所示:

要把认知服务用一个模拟的mock up service来代替,这个mock up service可以自己简单地用 ASP.NET 搭建一个,接收请求后,不做任何逻辑处理,直接返回JSON字符串,但是中间需要模拟认知服务的处理时间,故意延迟2~3秒。

另外一个原因是,认知服务比较复杂,可能不能满足很高的QPS的要求,而用自己的模拟服务可以到达极高的QPS,这样就不会正在测试中产生瓶颈。

网络环境为局域网内部,亦即客户端、中间层、模拟服务都在局域网内部即可,这样可以避免网络延迟带来的干扰。

测试方法与结果

在本例中,我们测试了8轮,每轮都模拟不同的并发用户数持续运行一小时,最终结果如下:

并发用户1 位用户3 位用户5 位用户10 位用户25 位用户50 位用户75 位用户100 位用户
中央处理器0%<1%<1%1%2.5%6%12%17%21%
内存(MB)110116150158164176260301335
延迟02.612.612.612.622.632.642.672.7
总要求01,3774,1246,88513,66634,22167,976100,948132,894
请求失败。000000000
PP2型0.000.381.151.913.809.5118.8828.0436.92

从图表可以看出,CPU/Memory/QPS都是线性增长的,意味着是可以预测的。延迟(Latency)是平缓的,不会因为并发用户变多而变慢,很健康。

可靠性测试 Stability Test

测试目的

在一个足够长的时间内持续测试服务,以检查其可靠性。"足够长"一般定义为12小时、48小时、72小时等等。可以认为,被测对象只要跑够了预定的时长,就算是稳定性过关了。

测试环境

同理,我们要测试的是中间层服务,而不是认知服务。

测试环境与上面相同,也是使用模拟的认知服务,因为72小时的测试时间,会发送大量的请求,很可能超出了当月限额而收取费用。

网络环境仍然使用局域网。

测试方法与结果

模拟10个并发用户,持续向中间层服务发请求12小时,测试结果如下表:

采样点中央处理器记忆延迟请求总数失败PP2型
1:00:002.5%140 米2.63 秒13,73003.81
2:00:002.5%160 米2.61 秒13,74103.82
3:00:002.5%150 米2.62 秒13,72803.81
......
总计/平均值2.5%150 米2.62164,77203.81

从CPU/Memory/Latency/QPS上来看,在12个小时内,都保持得非常稳定,说明服务器不会因为长时间运行而变得不稳定。

性能测试 Performance Test

测试目的

测试端对端(e2e)的请求/响应时间。想得到具体的数值,所以不需要很大的负载压力。

测试环境

这次我们需要使用真实的认知服务,网络环境也使用真实的互联网环境。亦即需要把中间服务层部署到互联网上后进行测试,因为用模拟环境和局域网测试出来的数据不能代表实际的用户使用情况。

测试方法与结果

模拟1个用户,持续向中间服务层发送请求1小时。然后模拟3个并发用户,持续向中间服务层发送请求10分钟。这两种方法都不会对认知服务带来很大的压力。

在得到了一系列的数据以后,每组数据都会有响应时间,我们把它们按照从长(慢)到短(快)的顺序排列,得到下图(其中横坐标是用户数,纵坐标是响应时间):

一般来说,我们要考察几个点,P90/P95/P99,比如P90的含义是:有90%的用户的响应时间小于等于2449ms。这意味着如果有极个别用户响应时间在10秒以上时,是一种正常的情况;如果很多用户(比如>5%)都在10秒以上就不正常了,需要立刻检查服务器的运行状态。

最后得到的结果如下表,亦即性能指标:

百分比P90型P95型P99型平均
关键绩效指标<3000毫秒<3250<4000不适用
服务器端处理时间2449毫秒2652毫秒3571毫秒1675毫秒
测试客户端 e2e 延迟3160毫秒3368毫秒4369毫秒2317毫秒

服务器端处理时间: 服务器端接收到请求到发出响应,所经过的时长。

测试客户端 e2e 延迟: 客户端发出请求到接收到响应,所经过的时长。

习题与进阶学习

增加OCR服务以提供识别文字的功能

在集成服务层增加可以识别具有标准模式的文字的服务,比如电话号码、网络地址、邮件地址,这需要同时在基础服务层增加OCR底层服务,并在任务调度层增加一个并行任务。

部署到实际的Azure环境提供真实服务

在本地测试好服务器的基本功能后,部署到Azure上去,看看代码在实际环境中运行会有什么问题。因为我们不能实时地监控服务器,所以需要在服务层上增加log功能。

开发Android/iOS应用来提供影像/视觉感知

可以选择像Bob同学那样,先用第一种方式直接访问微软认知服务,然后一步步演进到中间层服务模式。建议使用VS2017 + Xamarin利器来实现跨平台应用。

图像基本分类

在任务调度层,增加一个本地的图像分类器,如同“todo”里的preprocess,能够把输入图片分类成“有人脸”、“有地标”、“有文字”等,然后再根据信心指数调用名人服务或地标服务,以减轻服务器的负担,节省费用。比如,当"有地标"的信心指数小于0.5时,就终止后面的调用。这需要训练一个图片分类器,导出模型,再用Tools for AI做本地推理代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1382087.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SFP/SFP+/QSFP/QSFP+光模块和GTP/GTX/GTH/GTZ/GTY/GTM高速收发器

SFP/SFP/QSFP/QSFP光模块和GTP/GTX/GTH/GTZ/GTY/GTM高速收发器 SFP/SFP/QSFP/QSFP光模块概述SFPSFPQSFPQSFP关键参数说明 GTP/GTX/GTH/GTZ/GTY/GTM高速收发器区别XILINX 7系列FPGA中高速收发器使用 SFP/SFP/QSFP/QSFP光模块 概述 SFP&#xff08; small form-factor pluggabl…

小程序基础学习(多插槽)

先创建插槽 定义多插槽的每一个插槽的属性 在js文件中启用多插槽 在页面使用多插槽 组件代码 <!--components/my-slots/my-slots.wxml--><view class"container"><view class"left"> <slot name"left" ></slot>&…

人声处理用什么软件好 FL Studio 怎么修人声 人声处理软件 人声处理步骤

一、人声处理用什么软件好 现在人声处理软件还是非常多的&#xff0c;有专门的人声处理软件&#xff0c;也有具备人声处理功能的编曲软件。专门人声处理的软件操作比较简单&#xff0c;但是处理后的人声在使用的时候可能还需要进行再处理&#xff0c;这会比较麻烦。具备人声处…

nacos配置中心只能获取部分配置的问题

检查配置中心&#xff0c;在配置中心里是可以看到监听的服务地址的&#xff0c;但是却获取不到配置 nacos配置中心主要是在这个NacosConfigService的这个类下面。该接口下面主要有一些获取配置&#xff0c;发布配置&#xff0c;增加监听器&#xff0c;删除配置&#xff0c;删…

迅腾文化用网络集成化生态系统助力品牌之路的坚实后盾

商业竞争激烈&#xff0c;品牌不仅是企业的标志和形象&#xff0c;更是其核心价值和竞争力的体现。然而&#xff0c;企业在品牌推广过程中面临着诸多如缺乏有效的渠道管理、品牌形象模糊以及竞争激烈的市场环境等。这些阻碍着企业的品牌发展和市场占有率的提升。本文将通过企业…

匠心科技BLDC开发板原理图讲解

匠心科技BLDC开发板资料 链接&#xff1a;https://pan.baidu.com/s/1s5YjzRSDLKQvl86lBVAqKA?pwda6cx 提取码&#xff1a;a6cx 解压密码&#xff1a;JXKJ_RALDNWB站视频讲解&#xff08;&#xff09; 链接: 匠心科技直流无刷电机开发板原理图讲解 BLDC的开发板主要分为四个模…

canvas设置图形图案、文字图案

查看专栏目录 canvas示例教程100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

js检测网址是否可访问,javascript检测网址是否可访问,支持跨域;

js检测网址是否可访问&#xff0c;javascript检测网址是否可访问&#xff0c;支持跨域&#xff1b; <!DOCTYPE html> <html> <head><meta name"viewport" content"widthdevice-width" /><title>url检测是否可访问</tit…

Rust-trait

Rust语言中的trait是非常重要的概念。 在Rust中&#xff0c;trait这一个概念承担了多种职责。在中文里&#xff0c;trait可以翻译为“特征”“特点”“特性”等。 成员方法 trait中可以定义函数。用例子来说明&#xff0c;我们定义如下的trait: 上面这个trait包含了一个方法…

#Prompt##提示词工程##AIGC##LLM#使用大型预训练语言模型的关键考量

如果有不清楚的地方可以评论区留言&#xff0c;我会给大家补上的&#xff01; 本文包括&#xff1a; Prompt 的一些行业术语介绍 Prompt 写好提示词的方法经验介绍&#xff08;附示例教程&#xff09; LLM自身存在的问题&#xff08;可以用Prompt解决的以及无法用Prompt解决的&…

Linux基础工具的使用(yum,vim,gcc,g++,gdb,make/makefile)【详解】

目录 linux软件包管理器-yum什么是软件包&#xff1f;查找软件包如何安装软件卸载软件 linux编辑器 - vimvim的基本概念vim模式之间的切换vim命令模式各命令汇总vim底行模式各命令汇总 Linux编译器 - gcc/ggcc/g的作用gcc/g选项预处理编译汇编链接静态库与动态库 Linux调试器 -…

【python】正则表达式-快速信息匹配,过滤与检测

前言 菜某的总结&#xff0c;希望能够帮到大家。 正则表达式的概念 简单来说就是匹配信息&#xff0c;创建一个规则&#xff0c;匹配文本中符合这个规则的内容 作用领域 单单看他的概念可能觉得他的用途也就是查找&#xff0c;实际上他的用途很广泛 1.信息筛选&#xff0c…

一、QT的前世今

一、Qt是什么 1、Qt 是一个1991年由奇趣科技开发的跨平台C图形用户界面应用程序开发框架。它既可以开发GUI程序&#xff0c;也可用于开发非GUI程序&#xff0c;比如控制台工具和服务。 2、Qt是面向对象的框架&#xff0c;具有面向对象语言的特性&#xff1a;封装、继承、多态。…

电子学会2023年12月青少年软件编程(图形化)等级考试试卷(三级)真题,含答案解析

青少年软件编程(图形化)等级考试试卷(三级) 分数:100 题数:31 一、单选题(共18题,共50分) 1. 运行左图程序,想得到右图中的效果,红色框应填写的数值是?( ) A.

vmware和ubuntu镜像下载地址

这里有vmware16和ubuntu20.0下载 链接&#xff1a;https://pan.baidu.com/s/1i9IC-KnJlrVDbl6SJ5SIKQ?pwdy2dd 提取码&#xff1a;y2dd 链接&#xff1a;https://pan.baidu.com/s/1imqJVD2dLE1TB6jIrq1-Fg?pwd690f 提取码&#xff1a;690f 这个是我本人下的vmware17 密钥可…

超声波眼镜清洗机清洗眼镜会有伤害吗?适合洗眼镜超声波清洗机

眼镜作为日常生活中不可或缺的辅助视力工具&#xff0c;经常需要清洁保养以确保视力清晰和舒适佩戴。随着科技的发展&#xff0c;超声波眼镜清洗机成为越来越受欢迎的清洁方式。然而&#xff0c;很多人可能会担心使用超声波清洗机是否会对眼镜造成损害。但是可以很可以的告诉大…

Vulnhub-Lampiao

一、信息收集 nmap扫描 PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.7 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 1024 46:b1:99:60:7d:81:69:3c:ae:1f:c7:ff:c3:66:e3:10 (DSA) | 2048 f3:e8:88:f2:2d:d0:b2:54:0b:…

Xtuner大模型微调

Xtuner大模型微调 一、课程笔记 文档链接&#xff1a;https://github.com/InternLM/tutorial/blob/main/xtuner/README.md 视频链接&#xff1a; https://www.bilibili.com/video/BV1yK4y1B75J/ 大模型微调 大模型的训练利用了各类数据&#xff0c;可以说是一个通才&#xff…

基于Matlab/Simulink开发自动驾驶的解决方案

文章目录 处理自动驾驶数据 仿真自动驾驶场景 设计感知算法 设计规划和控制算法 生成代码和部署算法 集成和测试 参考文献 使用 MATLAB/Simulink开发自动驾驶&#xff0c;能够深入建模真实世界的行为、减少车辆测试并验证嵌入式软件的功能&#xff0c;从而推进自动驾驶感…

宝塔面板使用phpMyAdmin 502 Bad Gateway

第一步软件商店安装PHP 第二步设置phpMyAdmin,选择PHP版本 – 解决