基于存内计算架构的模型部署与映射优化

先进计算大赛背景:

‘’存内计算”架构通过消除存储与计算单元间的物理距离,突破传统冯·诺依曼架构的限制,自2016年起受到广泛关注,被视为国产算力发展的关键技术。 ​ 在存内计算架构中,权重布局对提高存算单元利用率和计算效率至关重要,是编译阶段优化的重点。优化算法的效率、阵列面积利用率和计算效率是神经网络在存内计算芯片上部署的关键指标。简而言之,"存内计算"技术通过优化,权重布局,提升了芯片性能和资源利用效率。

存算一体技术要点:

存算一体被认为是一种新型计算架构,与经典的冯诺依曼架构不同,存储器 本身即可进行计算,将存储单元和计算单元合为一体,省去了计算过程中数据搬 运环节,消除了由于数据搬运带来的功耗和延迟,从而进一步提升计算能效。

以知存科技的模拟存算计算方案为例,,首先将被乘矩阵的参数提 前存入存算单元,然后将乘数向量输入,在水平方向上,乘数在存算单元中完成 与被乘数的乘法操作,在垂直方向上,每个存算单元的乘法结果累加,最后得到 输出向量。

之所以以矩阵计算为例,是因为矩阵对于机器学习系统而言极为关键,它为数据表示提供了一种既简单又高效的方法。举例来说,输入数据(如图像里的像素集合)或者模型内部不同层之间的运行机制均能够借助矩阵来表示。所以,矩阵相乘运算在深度学习模型的总计算量当中占据着相当大的比重。实际上,在诸多当下流行的Transformer模型,如BERT、CLIP以及ChatGPT中,矩阵乘法的运行时长大约占其总运行时长的45 - 60%。矩阵乘法在卷积运算的计算过程里起着重要的作用,而卷积运算又是大多数计算机视觉模型的基础,也是许多高性能计算应用的核心部分。

这里我们使用的create函数如下:

def _create(name, pretrained=True, channels=3, classes=80, autoshape=True, verbose=True, device=None):from pathlib import Path
​from models.common import AutoShape, DetectMultiBackendfrom models.experimental import attempt_loadfrom models.yolo import ClassificationModel, DetectionModel, SegmentationModelfrom utils.downloads import attempt_downloadfrom utils.general import LOGGER, ROOT, check_requirements, intersect_dicts, loggingfrom utils.torch_utils import select_device
​if not verbose:LOGGER.setLevel(logging.WARNING)check_requirements(ROOT / "requirements.txt", exclude=("opencv-python", "tensorboard", "thop"))name = Path(name)path = name.with_suffix(".pt") if name.suffix == "" and not name.is_dir() else name  try:device = select_device(device)if pretrained and channels == 3 and classes == 80:try:model = DetectMultiBackend(path, device=device, fuse=autoshape)  if autoshape:if model.pt and isinstance(model.model, ClassificationModel):LOGGER.warning("WARNING ⚠️ YOLOv3 ClassificationModel is not yet AutoShape compatible. ""You must pass torch tensors in BCHW to this model, i.e. shape(1,3,224,224).")elif model.pt and isinstance(model.model, SegmentationModel):LOGGER.warning("WARNING ⚠️ YOLOv3 SegmentationModel is not yet AutoShape compatible. ""You will not be able to run inference with this model.")else:model = AutoShape(model)  # for file/URI/PIL/cv2/np inputs and NMSexcept Exception:model = attempt_load(path, device=device, fuse=False)  else:cfg = list((Path(__file__).parent / "models").rglob(f"{path.stem}.yaml"))[0]  model = DetectionModel(cfg, channels, classes)  # create modelif pretrained:ckpt = torch.load(attempt_download(path), map_location=device)  # loadcsd = ckpt["model"].float().state_dict()  # checkpoint state_dict as FP32csd = intersect_dicts(csd, model.state_dict(), exclude=["anchors"])  model.load_state_dict(csd, strict=False)  if len(ckpt["model"].names) == classes:model.names = ckpt["model"].names if not verbose:LOGGER.setLevel(logging.INFO)  # reset to defaultreturn model.to(device)
​except Exception as e:help_url = "https://docs.ultralytics.com/yolov5/tutorials/pytorch_hub_model_loading"s = f"{e}. Cache may be out of date, try `force_reload=True` or see {help_url} for help."raise Exception(s) from e

除此之外,我们还要用到基于存算一体的深度学习编译工具链,他和传统的编译器可大有不同,传统编译器是一种能够把高级编程语言转换为低级目标语言的程序,其编译流程可划分为前端和后端这两个部分。在编译过程中,前端负责解析高级语言,进而生成抽象语法树与中间表示;后端则负责生成目标代码。 深度学习编译器与传统编译器类似,是一种用于将深度学习神经网络模型部署到硬件平台的工具。它处在深度学习框架与硬件设备之间,把深度学习框架中所描述的模型定义当作输入内容,然后在各类深度学习硬件上生成高效的代码实现并将其作为输出结果。它是连接软硬件的桥梁,有着重要意义。而我们的作品就是运用了次深度学习编译工具链。下图为深度学习编译工具链常用设计框架。

witin_mapper是知存科技自研的用于神经网络映射的编译软件栈,可以将量化后的神经网络模型映射到WTM2101 MPU加速器上,是一种包括RiscV和MPU的完整解决方案,可以完成算子和图级别的转换和优化,将预训练权重编排到存算阵列中,并针对网络结构和算子给出存算优化方案,同时将不适合MPU运算的算子调度到CPU上运算,实现整网的调度,让神经网络开发人员高效快捷的将训练好的算法运行在WTM2101芯片上,极大缩短模型移植的开发周期并提高算法开发的效率。

Links : https://github.com/witmem/Witmem-Toolchain-WTM2101


可用工具:

在最开始我们做了模型准备,这个是官方提供的,然后通过官网下载模型可视化工具Netron软件。为后续工作做准备。紧接着我们获取模型中数据依赖关系以及权重矩阵块参数,这个过程总体来说不难,但是由于个人原因,在这里花费了很多精力。然后我们对应onnx文件的权重矩阵块组信息以及矩阵块之间的数据处理先后关系。到这里,一大步就已经跨过去了。

接下来,开始进行编译映射工作。读取了上面输出的结果,用其实现紧密排布如下图,

后面输出结果,使用存算阵列情况与各个阵列内的排布情况,如下图:

  • core_id:“空矩形”的序号

  • index:环节一中解析得到的权重矩阵的数据依赖顺序

  • w_clo_start:权重矩阵的左上角在“空矩形”中的列方向位置

  • w_row_start:权重矩阵的左上角在“空矩形”中的行方向位置


配置验证:

对于这一步,我们团队主要测试存算阵列的执行效率,排布的合理性,比如是否超出存算阵列的范围,是否存在矩阵块面积重叠的情况,以及存算阵列的面积利用率。

下面的run函数是我们的键盘手提供的,它能够对多种输入源进行处理,然后根据设定的参数进行推理、后处理,并将结果进行保存或显示。

@smart_inference_mode()
def run(weights=ROOT / "yolov5s-cls.pt",  # model.pt path(s)source=ROOT / "data/images",  # file/dir/URL/glob/screen/0(webcam)data=ROOT / "data/coco128.yaml",  # dataset.yaml pathimgsz=(224, 224),  # inference size (height, width)device="",  # cuda device, i.e. 0 or 0,1,2,3 or cpuview_img=False,  # show resultssave_txt=False,  # save results to *.txtnosave=False,  # do not save images/videosaugment=False,  # augmented inferencevisualize=False,  # visualize featuresupdate=False,  # update all modelsproject=ROOT / "runs/predict-cls",  # save results to project/namename="exp",  # save results to project/nameexist_ok=False,  # existing project/name ok, do not incrementhalf=False,  # use FP16 half-precision inferencednn=False,  # use OpenCV DNN for ONNX inferencevid_stride=1,  # video frame-rate stride
):"""Performs YOLOv3 classification inference on various input sources and saves or displays results."""source = str(source)save_img = not nosave and not source.endswith(".txt")  # save inference imagesis_file = Path(source).suffix[1:] in (IMG_FORMATS + VID_FORMATS)is_url = source.lower().startswith(("rtsp://", "rtmp://", "http://", "https://"))webcam = source.isnumeric() or source.endswith(".streams") or (is_url and not is_file)screenshot = source.lower().startswith("screen")if is_url and is_file:source = check_file(source)  # download
​# Directoriessave_dir = increment_path(Path(project) / name, exist_ok=exist_ok)  # increment run(save_dir / "labels" if save_txt else save_dir).mkdir(parents=True, exist_ok=True)  # make dir
​# Load modeldevice = select_device(device)model = DetectMultiBackend(weights, device=device, dnn=dnn, data=data, fp16=half)stride, names, pt = model.stride, model.names, model.ptimgsz = check_img_size(imgsz, s=stride)  # check image size
​# Dataloaderbs = 1  # batch_sizeif webcam:view_img = check_imshow(warn=True)dataset = LoadStreams(source, img_size=imgsz, transforms=classify_transforms(imgsz[0]), vid_stride=vid_stride)bs = len(dataset)elif screenshot:dataset = LoadScreenshots(source, img_size=imgsz, stride=stride, auto=pt)else:dataset = LoadImages(source, img_size=imgsz, transforms=classify_transforms(imgsz[0]), vid_stride=vid_stride)vid_path, vid_writer = [None] * bs, [None] * bs
​# Run inferencemodel.warmup(imgsz=(1 if pt else bs, 3, *imgsz))  # warmupseen, windows, dt = 0, [], (Profile(), Profile(), Profile())for path, im, im0s, vid_cap, s in dataset:with dt[0]:im = torch.Tensor(im).to(model.device)im = im.half() if model.fp16 else im.float()  # uint8 to fp16/32if len(im.shape) == 3:im = im[None]  # expand for batch dim
​# Inferencewith dt[1]:results = model(im)
​# Post-processwith dt[2]:pred = F.softmax(results, dim=1)  # probabilities
​# Process predictionsfor i, prob in enumerate(pred):  # per imageseen += 1if webcam:  # batch_size >= 1p, im0, frame = path[i], im0s[i].copy(), dataset.counts += f"{i}: "else:p, im0, frame = path, im0s.copy(), getattr(dataset, "frame", 0)
​p = Path(p)  # to Pathsave_path = str(save_dir / p.name)  # im.jpgtxt_path = str(save_dir / "labels" / p.stem) + ("" if dataset.mode == "image" else f"_{frame}")  # im.txt
​s += "{:g}x{:g} ".format(*im.shape[2:])  # print stringannotator = Annotator(im0, example=str(names), pil=True)
​# Print resultstop5i = prob.argsort(0, descending=True)[:5].tolist()  # top 5 indicess += f"{', '.join(f'{names[j]} {prob[j]:.2f}' for j in top5i)}, "
​# Write resultstext = "\n".join(f"{prob[j]:.2f} {names[j]}" for j in top5i)if save_img or view_img:  # Add bbox to imageannotator.text([32, 32], text, txt_color=(255, 255, 255))if save_txt:  # Write to filewith open(f"{txt_path}.txt", "a") as f:f.write(text + "\n")
​# Stream resultsim0 = annotator.result()if view_img:if platform.system() == "Linux" and p not in windows:windows.append(p)cv2.namedWindow(str(p), cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)  # allow window resize (Linux)cv2.resizeWindow(str(p), im0.shape[1], im0.shape[0])cv2.imshow(str(p), im0)cv2.waitKey(1)  # 1 millisecond
​# Save results (image with detections)if save_img:if dataset.mode == "image":cv2.imwrite(save_path, im0)else:  # 'video' or 'stream'if vid_path[i] != save_path:  # new videovid_path[i] = save_pathif isinstance(vid_writer[i], cv2.VideoWriter):vid_writer[i].release()  # release previous video writerif vid_cap:  # videofps = vid_cap.get(cv2.CAP_PROP_FPS)w = int(vid_cap.get(cv2.CAP_PROP_FRAME_WIDTH))h = int(vid_cap.get(cv2.CAP_PROP_FRAME_HEIGHT))else:  # streamfps, w, h = 30, im0.shape[1], im0.shape[0]save_path = str(Path(save_path).with_suffix(".mp4"))  # force *.mp4 suffix on results videosvid_writer[i] = cv2.VideoWriter(save_path, cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))vid_writer[i].write(im0)
​# Print time (inference-only)LOGGER.info(f"{s}{dt[1].dt * 1E3:.1f}ms")
​# Print resultst = tuple(x.t / seen * 1e3 for x in dt)  # speeds per imageLOGGER.info(f"Speed: %.1fms pre-process, %.1fms inference, %.1fms NMS per image at shape {(1, 3, *imgsz)}" % t)if save_txt or save_img:s = f"\n{len(list(save_dir.glob('labels/*.txt')))} labels saved to {save_dir / 'labels'}" if save_txt else ""LOGGER.info(f"Results saved to {colorstr('bold', save_dir)}{s}")if update:strip_optimizer(weights[0])  # update model (to fix SourceChangeWarning)

通过以上的工作,在最后分析了权重矩阵的计算依赖关系。到这里我们的作品就差不多了。

存内计算开发者社区:存内计算开发者社区-CSDN社区云

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

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

相关文章

海外盲盒APP为盲盒出海助力,拓展海外市场

潮玩市场是一个具有全球化的行业在全球都具有非常高的发展潜力,随着国内盲盒市场的饱和,拓展海外市场对盲盒企业至关重要。近年来,盲盒已经在海外市场取得了一定的成绩,这为企业拓展海外市场奠定了发展基础。 目前,在…

虚拟机(VMware)安装,保姆级教程(附所有安装包及所有安装步骤)

1.安装包下载 1.1VMware下载 VMware安装包 提取码:b9ds 1.2镜像下载 镜像安装包 提取码:hbtq 2.配置虚拟机向导 2.1配置虚拟机向导 2.2选择虚拟机硬件兼容性 2.3安装客户机操作系统 2.4简易安装信息 2.5命名虚拟机 2.6处理器配置 #这个根据自己…

“数字化、数字化流程、流程数字化转型、端到端流程”概念解析

​头一次看到能把“数字化”“数字化流程”“流程数字化转型”和“端到端流程”说的这么清楚的! 所谓的“数字化”是指新一代的数字化技术,比如移动、社交、云技术、大数据、人工智能、区块链、数字孪生等。这批新技术已经开始改变人们的工作方式&#x…

VBA技术资料MF198:禁用下拉拖放

我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的工作效率,而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套,分为初级、中级、高级三大部分,教程是对VBA的系统讲解&#…

案例精选 | 聚铭助力河北省某市公安局筑牢网络安全防护屏障

近年来,各级公安机关积极响应信息化发展趋势,致力于提升公安工作的效能与核心战斗力。河北省某市公安局作为主管全市公安工作的市政府部门,承担着打击违法犯罪、维护社会稳定的重任。随着信息化建设的推进,局内系统数量、种类及数…

模板初阶(C++)

初识模板 模板分为 函数模板和类模板这两种,模板可以理解为是一套固有的方法,通过改变里面不同的载体( 参数类型)进而调高代码的复用性。这是一个经典案例,在不使用模板的情况下,若遇见不同类型的参数&…

Linux——k8s认识

计算资源隔离 - 更方便进行高并发架构的维护和升级 - 架构管理的灵活性更高,不再以单个节点的物理资源作为基础 技术: - 硬件辅助虚拟化 - 容器技术 在企业部署方案中,很少以单节点实现虚拟化和容器技术,一般以集群状态来运…

PCL KD树的使用

目录 一、概述 1.1原理 1.1.1 数据拆分过程 1.1.2 树的构建示例 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1KD树构建与查询: 2.1.2 k近邻搜索 2.1.3半径搜索 2.2完整代码 三、实现效果 3.1处理后点云 3.2数据显示 PCL点云算法汇总及实战…

neo4j导入csv数据

neo4j数据可视化实践 手动输入数据 - 官方democsv数据导入准备数据数据处理导入步骤① 导入疾病表格② 导入药物表格③导入疾病-药物关系表格 爬虫的csv文件 手动输入数据 - 官方demo 点击之后,按照左边10张图中的代码,复制粘贴熟悉语法 效果如下 csv数据…

(十六)Ubuntu 20.04 下搭建PX4+MATLAB 仿真环境(HITL)

在文章(十五)Ubuntu 20.04 下搭建PX4MATLAB 仿真环境我们学习了如何配置仿真环境,在本节,主要进行HITL的仿真环境搭建。 根据(十五)Ubuntu 20.04 下搭建PX4MATLAB 仿真环境完成配置到如下界面:…

STM32F1+HAL库+FreeTOTS学习11——延时函数API

STM32F1HAL库FreeTOTS学习11——延时函数API 延时函数API1. vTaskDelay()2. vTaskDelayUntil()3. xTaskDelayUntil()相对延时和绝对延时的区别4. xTaskAbortDelay() 上一期,我们学习了任务相关API使用,这一期我们开始学习FreeRTOS延时函数的API使用 延时…

MySQL--导入SQL文件(命令行导入)

MySQL--导入SQL文件 一、前言二、导入SQL文件 一、前言 用可视化编辑工具编写,并且在控制台输入命令行在MySQL中导入SQL文件。 在导入SQL文件之前查看了目前存在的数据库 **目标:**在可视化编辑工具(这里以word文档为例)中编写SQL语句&…

【算法竞赛】栈

栈的特点是"先进后出"。 栈在生活中的原型有:坐电梯,先进电梯的被挤在最里面,只能最后出来;一管泡腾片,最先放进管子的药片位于最底层,最后被拿出来。 栈只有唯一的出入口,从这个口进入,也从这个口弹出,这是它与队列最大的区别。 队列有一个入…

【动态规划】最大正方形

最大正方形(难度:中等) 该题对应力扣网址 思路 min_valuemin({dp[i-1][j-1],dp[i-1][j],dp[i][j-1]}) dp[i][j]min_value 关键点是正方形的右下角(n>1时),通过画图,可以看出,在基础正方形22中&#x…

unordered_map/set(底层实现)——C++

目录 前言: 1.开散列 1. 开散列概念 2. 开散列实现 2.1哈希链表结构体的定义 2.2哈希表类即私有成员变量 2.3哈希表的初始化 2.4迭代器的实现 1.迭代器的结构 2.构造 3.* 4.-> 5. 6.! 2.5begin和end 2.6插入 2.7Find查找 2.8erase删除 3.unordered_ma…

在vue中:style 的几种使用方式

在日常开发中:style的使用也是比较常见的&#xff1a; 亲测有效 1.最通用的写法 <p :style"{fontFamily:arr.conFontFamily,color:arr.conFontColor,backgroundColor:arr.conBgColor}">{{con.title}}</p> 2.三元表达式 <a :style"{height:…

Gitlab学习(006 gitlab操作)

尚硅谷2024最新Git企业实战教程&#xff0c;全方位学习git与gitlab 总时长 5:42:00 共40P 此文章包含第21p-第24p的内容 文章目录 git登录修改root密码 设置修改语言取消相对时间勾选 团队管理创建用户创建一个管理员登录管理员账号创建一个普通用户登录普通用户账号 群组管理…

第6天:趋势轮动策略开发(年化18.8%,大小盘轮动加择时)

原创内容第655篇&#xff0c;专注量化投资、个人成长与财富自由。 轮动策略是一种投资策略&#xff0c;它涉及在不同的资产类别、行业或市场之间进行切换&#xff0c;以捕捉市场机会并优化投资组合的表现。 这种策略的核心在于识别并利用不同资产或市场的相对强弱&#xff0c…

自然语言处理-基于注意力机制的文本匹配

背景&#xff1a; 任务三&#xff1a;基于注意力机制的文本匹配 输入两个句子判断&#xff0c;判断它们之间的关系。参考ESIM&#xff08;可以只用LSTM&#xff0c;忽略Tree-LSTM&#xff09;&#xff0c;用双向的注意力机制实现。 参考 《神经网络与深度学习》 第7章 Reaso…

clousx6整点报时指令怎么写?

&#x1f3c6;本文收录于《全栈Bug调优(实战版)》专栏&#xff0c;主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&am…