全球AI大模型企业是如何炼成(国内篇)?

智能计算芯世界 2023-11-21 07:30
AI大模型是一个资本密集、人才密集和数据密集的产业,如何形成“数据、模型、应用”的飞轮,是大模型企业成功的关键。海外企业中,微软&OpenAI、谷歌已经逐步形成 AI 大模型的飞轮。
上篇分享了“全球AI大模型企业是如何炼成(海外篇)?”,本文分析国内篇,国内百度、阿里、商汤、华为等积极加入,行业呈现“百模大战”的竞争格局,能否形成飞轮是最后能否胜出的关键。
本文来自“人工智能行业报告:AI2.0、AI大模型、算力、AI赋能(2023)”,详细介绍全球(海外、国内)AI大模型算力、模型、应用等现状,本篇为国内篇。更多内容参考400+份重磅ChatGPT专业报告(合集)

国内大模型:百度、阿里、腾讯、华为、商汤、讯飞

国内大模型训练企业中,百度具备先发优势,芯片层、框架层、模型层和应用层布局完善。阿里紧随其后,在芯片层、模型层、应用层均有布局,并宣布将旗下所有产品接入通义大模型。腾讯步调稳健,持续研发,在今年以来的大模型热潮中发声克制,并未宣布更多模型、应用进展。华为的大模型布局更偏向基础设施,在芯片层、框架层和模型层均有布局,主要赋能 B 端客户。商汤的 AI 布局涵盖推理芯片、模型层和应用层,其以 CV 起家,应用层面不仅涵盖文字生成能力,同时包括多模态能力。讯飞的 AI 布局主要涵盖模型层、应用层。

1、百度:昆仑芯+飞桨平台+文心大模型,构建广泛应用端生态

百度是当前唯一一家在芯片层、框架层、模型层和应用层都有领先产品布局的企业,四层架构相互协同优化,可以显著地降本增效。在芯片层,百度昆仑芯科技已实现两代通用 AI芯片“昆仑”的量产及应用,为大模型落地提供强大算力支持。在框架层,“飞桨”是国内首个自主研发的产业级深度学习平台,集基础模型库、端到端开发套件和工具组件于一体,有效支持文心大模型高效、稳定训练。在模型层,“文心大模型”包括基础大模型、任务大模型、行业大模型三级体系,全面满足产业应用需求。在应用层,文心已大规模应用于百度自有业务的各类产品,并通过企业级平台“文心千帆”进一步推动生态构建。

算力:两代自研通用 AI 芯片“昆仑”支持大模型落地

百度旗下的芯片公司昆仑芯科技已实现两代通用 AI 芯片产品的量产及落地应用。昆仑芯1 代 AI 芯片于 2020 年量产,是国内唯一一款经历过互联网大规模核心算法考验的云端 AI芯片,当前已被广泛部署在互联网、工业制造、智慧城市、智慧交通、科研等领域。昆仑芯 2 代 AI 芯片于 2021 年 8 月量产发布,是国内首款采用 GDDR6 显存的通用 AI 芯片,相比昆仑芯 1 代 AI 芯片性能提升 2-3 倍,且在通用性、易用性方面也有显著增强。目前,昆仑芯已在百度搜索等业务场景落地,也为大模型训练提供底层算力支撑。百度之外,昆仑芯还可为客户提供大模型定制服务,凭借强大算力为大模型落地提供全流程支持。

框架:产业级深度学习平台“飞桨”为大模型构建提供有力支撑

我国首个自主研发、功能丰富、开源开放的产业级深度学习平台飞桨(PaddlePaddle)是百度大模型背后的有力支撑。飞桨以百度多年的深度学习技术研究和业务应用为基础,集深度学习核心训练和推理框架、基础模型库、端到端开发套件和丰富的工具组件于一体,有效支持文心大模型高效、稳定训练。截至目前,飞桨已和 22 家国内外硬件厂商完成了超过 30 种芯片的适配和联合优化,国产芯片适配第一。

文心大模型:“基础+任务+行业”大模型三层体系全面满足产业应用需求

百度文心大模型体系构建了文心大模型、工具与平台两层体系。在模型层,文心大模型包括基础大模型、任务大模型、行业大模型三级体系。基础大模型针对特定任务预训练构建任务大模型,任务大模型结合垂直领域数据和知识进一步形成行业大模型,行业大模型则在应用场景的数据反哺基础大模型优化。在工具与平台层,大模型开发套件、文心 API以及提供全流程开箱即用大模型能力的 EasyDL 和 BML 开发平台,帮助全方位降低应用门槛。

应用:大模型生态逐步构建,推动 AI 落地产业

文心大模型是目前国内预训练大模型应用端生态最好的大模型之一。在百度自有业务中,文心已大规模应用于百度内部的各类产品,包含百度搜索、度小满金融、小度智能屏、百度地图等。例如,度小满的智能征信中台将文心 ERNIE 大模型应用在征信报告的解读上,能够将报告解读出 40 万维的风险变量。在百度业务之外,文心大模型联合国网、浦发、中国航天、人民网等企业推出了 11 个行业大模型,让大模型加速推动行业的智能化转型升级。

2、阿里巴巴:云上赋智,拥抱消费互联网 AI 新时代

2022 年 9 月,阿里巴巴发布通义大模型,该模型由统一底座层、通用模型层、行业模型层组成,是国内首个统一 AI 底座模型,而统一AI 模型可以充分利用多种感知模态的数据,从而获得更加丰富和准确的信息,有效解决了传统大模型通用性和易用性欠缺的问题。

1)统一底座层:通义统一底座中的 M6-OFA 模型,在不引入新增结构的情况下,可同时处理图像描述、视觉定位、文生图、视觉蕴含、文档摘要等 10 余项单模态和跨模态任务。

2)通用模型层:覆盖自然语言处理、多模态、计算机视觉。包括 NLP 模型通义AliceMind,多模态模型通义-M6,CV 模型通义-CV 三大模型。2023 年 4 月 7 日,阿里巴巴推出大规模语言模型通义千问,进一步丰富阿里巴巴在通用模型层的产品形态。

3)行业模型层:深入电商、医疗、法律、金融、娱乐等行业,通用与专业领域大小模型协同,让通义大模型系列可兼顾性能最优化与低成本落地。

3、腾讯:大模型赋能长尾商家内容自制,提升整体创意和投放效率

腾讯以太极平台为底层,借力混元 AI 和广告两大模型,推出 4 大广告系统,覆盖广告内容理解、智能制作审核、广告推荐模型等环节,其他方案包括视频自动生成,模型定制化和动态投放等。根据腾讯广告公众号,在 DCO 系统加持下,广告曝光改善 5%,流水和GMV 分别提升 10%和 9%。我们认为,未来腾讯或推出更多 AIGC 应用,视频号、朋友圈、小程序等都将受益于效率改善,或迎来更多提价空间。

腾讯混元AI大模型:四大技术平台。以混元大模型为底座,腾讯细分研发出四大技术平台,分别为“巨阙”系统主攻广告内容理解、“乾坤”聚焦广告智能创作、“神针”侧重广告智能审核、“天印”主打广告指纹系统。

混元AI大模型能够自动将广告文案生成视频。目前混元AI大模型已能够实现广告智能制作,即通过AIGC自动将广告文案生成视频,大大地提高了系统的理解能力、行业特征的洞察力以及文案创意的生成效率,从而有效降低了广告视频制作的成本。

3、华为:昇腾芯片+MindSpore+盘古大模型,应用场景落地可期

算力:以自研 AI 芯片昇腾作为根基,打造 AI 产业平台

华为昇腾芯片包括用于训练的算力最强 AI 芯片昇腾 910,以及用于推理的全栈全场景 AI芯片昇腾 310。2019 年 8 月推出的昇腾 910 算力超英伟达 Tesla V100 一倍,在同等功耗下拥有的算力资源达到了当时业内最佳水平的两倍。目前,“昇腾 AI”基础软硬件平台已成功孵化和适配了 30 多个主流大模型,为我国一半以上的原生大模型提供算力支撑。基于该平台,昇腾 AI 产业已与 20 多家硬件伙伴和 1100 多家软件伙伴建立了合作关系,并共同推出了 2000 多个行业 AI 解决方案,参与其中的开发者数量突破 150 万。

框架:深度学习框架 MindSpore 提升模型开发效率

深度学习框架 MindSpore 从训练推理部署全流程支撑模型高效开发,是国内社区中最活跃、关注度最高、被应用最多的框架之一。匹配昇腾 AI 处理器,MindSpore 有效克服 AI计算的复杂性和算力的多样性挑战,打造面向端、边、云的全场景 AI 基础设施方案,让芯片的强大算力能够以最高效的方式被开发者们利用。面向大模型开发场景,MindSpore 提供系列工具及套件,发挥软硬件综合优势,从训练推理部署全流程支撑模型高效开发。同时,MindSpore 可兼容第三方 AI 框架生态,以实现模型的快速迁移。

盘古大模型:赋能千行百业的三阶段体系

华为云盘古大模型于 2021 年 4 月正式发布,到 2022 年聚焦行业应用落地,已经基于一站式 AI 开发平台 ModelArts,发展出包括基础大模型(L0)、行业大模型(L1)、行业细分场景模型(L2)三大阶段的成熟体系,让 AI 开发由作坊式转变为工业化开发的新模式,赋能千行百业。具体来说,盘古大模型的三层体系架构包含:1)L0 基础大模型:30 亿参数的 CV 大模型在业界首次实现模型按需抽取,千亿参数和 40TB 训练数据的 NLP 大模型在在 CLUE 榜单实现业界领先,科学计算大模型致力于解决各种科学问题、促进基础科学的发展;2)L1 行业大模型:涵盖矿山、气象、药物、分子、电力、海浪、金融等行业;3)L2 场景模型:包含金融 OCR、电力巡检、建筑能耗优化等场景。

应用:行业大模型逐步落地,场景应用可期

盘古CV大模型可以赋能分类、识别、检测等视觉场景。华为已基于 CV 大模型推出矿山大模型、电力大模型等行业大模型,推动相关工业领域安全高效作业。在华为与能源集团合作推出的盘古矿山大模型中,模型能够解决 AI 在煤矿行业落地难、门槛高等问题。例如,在煤矿主运场景中,AI 主运智能监测系统的异物识别准确率达 98%,实现全时段巡检,避免因漏检造成的安全事故;在作业场景中,掘进作业序列智能监测的动作规范识别准确率超过 95%,保障井下作业安全。

4、商汤:SenseCore 大装置+日日新大模型

算力:基于 AI 大装置 SenseCore,以 AI 模型赋能四大业务

商汤基于 AI 大装置 SenseCore 辅助自身业务开展。AI 大装置 SenseCore 打通了算力、算法和平台之间的连接与协同,构建成一整套端到端的架构体系;基于 AI 大装置SenseCore,商汤通过 22,000+商用 AI 模型,赋能智慧商业、智慧城市、智慧生活和智慧汽车四大业务。

日日新大模型:构建面向 AGI 的核心能力,驱动垂直行业降本增效

商汤是国内最早布局 AI 大模型的企业之一,已实现 CV、NLP、多模态等大模型的全面布局。2019 年已经发布了拥有 10 亿参数的图像大模型,2022 发布的视觉模型参数量达到320 亿,是全球最大的通用视觉模型之一,能够实现高性能的目标检测、图像分割和多物体识别算法等功能。今年 3 月推出多模态大模型“书生 2.5”,具备图像描述、视觉问答、视觉推理、文字识别、文生图、文本检索视觉内容等功能,在国内处于领先地位。

应用:MaaS 模式可能成为重要新趋势

商汤日日新大模型开放 API 体系包含自然语言生成 API、图片生成 API、视觉通用感知任务 API 和标注 API。此外,商汤还提供了数据标注、模型训练及微调等一系列 MaaS 服务。近期,我们注意到,英伟达,百度,商汤等企业都提出了类似 MaaS 的新商业模式,其核心是利用自己已经拥有的通用大模型,帮助企业以专有数据创建专有模型。

篇幅所限,更多厂商技术分析请参考“人工智能行业报告:AI2.0、AI大模型、算力、AI赋能(2023)”。
下载链接:
通用CPU性能基准测试研究综述(2023)
2023全球半导体与集成电路产业发展研究专题报告
中国智能汽车车载芯片发展研究报告
《海光CPU+DCU技术研究报告合集(上)》 
1、海光信息:国产巨无霸,引领“中国芯” 
2、国产CPU厂商领军者,进入快速增长期 
3、国产CPU领军,加速突破高端市场 
4、国产CPU领军,受益于行业信创加速,成长空间广阔 
5、国产高端处理器龙头,CPU+DCU齐赋能 
6、国产微处理器产业的领军者"
《海光CPU+DCU技术研究报告合集(下)》 
1、达梦与海光:聚焦信创新股中的软硬龙头 
2、计算机行业深度报告:曙光很近,海光不远,国产x86算力生态崛起 
3、进击的国产CPU和GPU领航者 
4、信创硬件龙头 
5、行业信创龙头,国产 CPU 之光 
6、专注服务器与数据中心,高端处理器企业乘风国产替代
基于鲲鹏处理器的国产高性能计算集群实践
算力大时代,AI算力产业链全景梳理(2023)
AI算力行业深度:GPU全球格局分析(2023)
人工智能行业报告:AI2.0、AI大模型、算力、AI赋能(2023)
《华为产业链深度系列研究合集(2023)》
液冷技术要点汇总

《数据中心液冷技术合集(2023)》

1、电信运营商液冷技术白皮书(2023) 

2、浸没式液冷数据中心运维白皮书 

3、运营商力推液冷,中兴液冷技术领先(2023)

《2023年液冷技术白皮书汇总》

1、浸没式液冷数据中心热回收白皮书(2023) 2、数据中心绿色设计白皮书(2023)

《数据中心液冷技术合集》

1、集装箱冷板式液冷数据中心技术规范 

2、浸没式液冷发展迅速,“巨芯冷却液”实现国产突破 

3、两相浸没式液冷—系统制造的理想实践 

4、AIGC加速芯片级液冷散热市场爆发

《液冷技术专题》

1、中国液冷数据中心发展白皮书 

2、全浸没式液冷数据中心解决方案 

3、浸没液冷数据中心规范 

4、喷淋式直接液冷数据中心设计规范 

5、单相浸没式直接液冷数据中心设计规范

《液冷服务器技术合集》

1、某液冷服务器性能测试台的液冷系统设计

2、浸没液冷服务器可靠性白皮书 

3、天蝎5.0浸没式液冷整机柜技术规范


本号资料全部上传至知识星球,更多内容请登录智能计算芯知识(知识星球)星球下载全部资料。




免责申明:本号聚焦相关技术分享,内容观点不代表本号立场,可追溯内容均注明来源,发布文章若存在版权等问题,请留言联系删除,谢谢。


温馨提示:

请搜索“AI_Architect”或“扫码”关注公众号实时掌握深度技术分享,点击“阅读原文”获取更多原创技术干货。

智能计算芯世界 聚焦人工智能、芯片设计、异构计算、高性能计算等领域专业知识分享.
评论 (0)
  • 首个基于Transformer的分割检测+视觉大模型视频课程(23年新课+源码+课件)
    自动驾驶是高安全型应用,需要高性能和高可靠的深度学习模型,Vision Transformer是理想的选摔。现在主流的自动驾驶感知算法基本都使用了Vision Transformer相关技术,比如分割、2D/3D检测,以及最近大火的大模型 (如SAM),Vision Transformer在自动驾驶领域的落地方面遍地开花。5一方面,在自动驾驶或图像处理相关算法岗位的面试题中,Vision Transformer是必考题,需要对其理论知识有深入理解,并且在项目中真实的使用过相关技术。

    Transformer出自于Google于2017年发表的论文《Attention is all you need》,最开始是用于机器翻译,并且取得了非常好的效果。但是自提出以来,Transformer不仅仅在NLP领域大放异彩,并且在CV、RS等领域也取得了非常不错的表现。尤其是2020年,绝对称得上是Transformer的元年,比如在CV领域,基于Transformer的模型横扫各大榜单,完爆基于CNN的模型。为什么Transformer模型表现如此优异?它的原理是什么?它成功的关键又包含哪些?本文将简要地回答一下这些问题。

    我们知道Transformer模型最初是用于机器翻译的,机器翻译应用的输入是某种语言的一个句子,输出是另外一种语言的句子。
    var i *int = nil
    fmt.Println("i.size:", unsafe.Sizeof(i)) //8

    var i8 *int8 = nil
    fmt.Println("i8.size:", unsafe.Sizeof(i8)) //8

    var s *string = nil
    fmt.Println("s.size:", unsafe.Sizeof(s)) //8

    var ps *struct{} = nil
    fmt.Println("ps.size:", unsafe.Sizeof(ps)) //8

    var si []int = nil
    var si1 []int = nil
    fmt.Println("si.size:", unsafe.Sizeof(si)) //24

    var ii interface{} = nil
    fmt.Println("ii.size:", unsafe.Sizeof(ii)) //16
    我们以生成我,爱,机器,学习,翻译成<bos>,i,love,machine,learning,<eos>这个例子做生成过程来解释。
    训练:

    把“我/爱/机器/学习”embedding后输入到encoder里去,最后一层的encoder最终输出的outputs [10, 512](假设我们采用的embedding长度为512,而且batch size = 1),此outputs 乘以新的参数矩阵,可以作为decoder里每一层用到的K和V;
    将<bos>作为decoder的初始输入,将decoder的最大概率输出词向量A1和‘i’做cross entropy(交叉熵)计算error。
    将<bos>,“i” 作为decoder的输入,将decoder的最大概率输出词 A2 和‘love’做cross entropy计算error。
    将<bos>,“i”,“love” 作为decoder的输入,将decoder的最大概率输出词A3和’machine’ 做cross entropy计算error。
    将<bos>,“i”,"love ",“machine” 作为decoder的输入,将decoder最大概率输出词A4和‘learning’做cross entropy计算error。
    将<bos>,“i”,"love ",“machine”,“learning” 作为decoder的输入,将decoder最大概率输出词A5和终止符做cross entropy计算error。
    那么并行的时候是怎么做的呢,我们会有一个mask矩阵在这叫seq mask,因为他起到的作用是在decoder编码我们的target seq的时候对每一个词的生成遮盖它之后的词的信息。
    func main() {
    s := []string{"a", "b", "c"}
    fmt.Println("s:origin", s)
    changes1(s)
    fmt.Println("s:f1", s)

    changes2(s)
    fmt.Println("s:f2", s)

    changes3(s)
    fmt.Println("s:f3", s)
    }

    func changes1(s []string) {
    var tmp = []string{"x", "y", "z"}
    s = tmp
    }

    func changes2(s []string) {
    // item只是一个副本,不能改变s中元素的值
    for i, item := range s {
    item = "d"
    fmt.Printf("item=%s;s[%d]=%s", item, i, s[i])
    }
    }

    func changes3(s []string) {
    for i := range s {
    s[i] = "d"
    }
    }

    首先我们需要为每个输入向量(也就是词向量)创建3个向量,分别叫做Query、Key、Value。那么如何创建呢?我们可以对输入词向量分别乘上3个矩阵来得到Q、K、V向量,这3个矩阵的参数在训练的过程是可以训练的。注意Q、K、V向量的维度是一样的,但是它们的维度可以比输入词向量小一点,比如设置成64,其实这步也不是必要的,这样设置主要是为了与后面的Mulit-head注意力机制保持一致(当使用8头注意力时,单头所处理的词向量维度为512/8=64,此时Q、K、V向量与输入词向量就一致了)。我们假设输入序列为英文的"Thinking Machines"
    想要深度理解Attention机制,就需要了解一下它产生的背景、在哪类问题下产生,以及最初是为了解决什么问题而产生。

    首先回顾一下机器翻译领域的模型演进历史:

    机器翻译是从RNN开始跨入神经网络机器翻译时代的,几个比较重要的阶段分别是: Simple RNN, Contextualize RNN,Contextualized RNN with attention, Transformer(2017),下面来一一介绍。

    「Simple RNN」 :这个encoder-decoder模型结构中,encoder将整个源端序列(不论长度)压缩成一个向量(encoder output),源端信息和decoder之间唯一的联系只是: encoder output会作为decoder的initial states的输入。这样带来一个显而易见的问题就是,随着decoder长度的增加,encoder output的信息会衰减。
    func main(){
    var c = make(chan int)
    fmt.Printf("c.pointer=%p\n", c) //c.pointer=0xc000022180
    go func() {
    c <- 1
    addChannel(c)
    close(c)
    }()

    for item := range c {
    //item: 1
    //item: 2
    fmt.Println("item:", item)
    }
    }

    func addChannel(done chan int) {
    done <- 2
    fmt.Printf("done.pointer=%p\n", done) //done.pointer=0xc000022180
    }
    在测试模型的时候,Test:decoder没有label,采用自回归一个词一个词的输出,要翻译的中文正常从encoder并行输入(和训练的时候一样)得到每个单词的embedding,然后decoder第一次先输入bos再此表中的id,得到翻译的第一个单词,然后自回归,如此循环直到预测达到eos停止标记
    type visit struct {
    a1  unsafe.Pointer
    a2  unsafe.Pointer
    typ Type
    }

    func deepValueEqual(v1, v2 Value, visited map[visit]bool) bool {
    if !v1.IsValid() || !v2.IsValid() {
    return v1.IsValid() == v2.IsValid()
    }
    if v1.Type() != v2.Type() {
    return false
    }

    // We want to avoid putting more in the visited map than we need to.
    // For any possible reference cycle that might be encountered,
    // hard(v1, v2) needs to return true for at least one of the types in the cycle,
    // and it's safe and valid to get Value's internal pointer.
    hard := func(v1, v2 Value) bool {
    switch v1.Kind() {
    case Pointer:
    if v1.typ.ptrdata == 0 {
    // not-in-heap pointers can't be cyclic.
    // At least, all of our current uses of runtime/internal/sys.NotInHeap
    // have that property. The runtime ones aren't cyclic (and we don't use
    // DeepEqual on them anyway), and the cgo-generated ones are
    // all empty structs.
    return false
    }
    fallthrough
    case Map, Slice, Interface:
    // Nil pointers cannot be cyclic. Avoid putting them in the visited map.
    return !v1.IsNil() && !v2.IsNil()
    }
    return false
    }

    if hard(v1, v2) {
    // For a Pointer or Map value, we need to check flagIndir,
    // which we do by calling the pointer method.
    // For Slice or Interface, flagIndir is always set,
    // and using v.ptr suffices.
    ptrval := func(v Value) unsafe.Pointer {
    switch v.Kind() {
    case Pointer, Map:
    return v.pointer()
    default:
    return v.ptr
    }
    }
    addr1 := ptrval(v1)
    addr2 := ptrval(v2)
    if uintptr(addr1) > uintptr(addr2) {
    // Canonicalize order to reduce number of entries in visited.
    // Assumes non-moving garbage collector.
    addr1, addr2 = addr2, addr1
    }

    // Short circuit if references are already seen.
    typ := v1.Type()
    v := visit{addr1, addr2, typ}
    if visited[v] {
    return true
    }

    // Remember for later.
    visited[v] = true
    }

    switch v1.Kind() {
    case Array:
    for i := 0; i < v1.Len(); i++ {
    if !deepValueEqual(v1.Index(i), v2.Index(i), visited) {
    return false
    }
    }
    return true
    case Slice:
    if v1.IsNil() != v2.IsNil() {
    return false
    }
    if v1.Len() != v2.Len() {
    return false
    }
    if v1.UnsafePointer() == v2.UnsafePointer() {
    return true
    }
    // Special case for []byte, which is common.
    if v1.Type().Elem().Kind() == Uint8 {
    return bytealg.Equal(v1.Bytes(), v2.Bytes())
    }
    for i := 0; i < v1.Len(); i++ {
    if !deepValueEqual(v1.Index(i), v2.Index(i), visited) {
    return false
    }
    }
    return true
    case Interface:
    if v1.IsNil() || v2.IsNil() {
    return v1.IsNil() == v2.IsNil()
    }
    return deepValueEqual(v1.Elem(), v2.Elem(), visited)
    case Pointer:
    if v1.UnsafePointer() == v2.UnsafePointer() {
    return true
    }
    return deepValueEqual(v1.Elem(), v2.Elem(), visited)
    case Struct:
    for i, n := 0, v1.NumField(); i < n; i++ {
    if !deepValueEqual(v1.Field(i), v2.Field(i), visited) {
    return false
    }
    }
    return true
    case Map:
    if v1.IsNil() != v2.IsNil() {
    return false
    }
    if v1.Len() != v2.Len() {
    return false
    }
    if v1.UnsafePointer() == v2.UnsafePointer() {
    return true
    }
    for _, k := range v1.MapKeys() {
    val1 := v1.MapIndex(k)
    val2 := v2.MapIndex(k)
    if !val1.IsValid() || !val2.IsValid() || !deepValueEqual(val1, val2, visited) {
    return false
    }
    }
    return true
    case Func:
    if v1.IsNil() && v2.IsNil() {
    return true
    }
    // Can't do better than this:
    return false
    case Int, Int8, Int16, Int32, Int64:
    return v1.Int() == v2.Int()
    case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr:
    return v1.Uint() == v2.Uint()
    case String:
    return v1.String() == v2.String()
    case Bool:
    return v1.Bool() == v2.Bool()
    case Float32, Float64:
    return v1.Float() == v2.Float()
    case Complex64, Complex128:
    return v1.Complex() == v2.Complex()
    default:
    // Normal equality suffices
    return valueInterface(v1, false) == valueInterface(v2, false)
    }
    }
    这便是encoder的整体计算流程图了,Transformer模型中堆叠了多个这样的encoder,无非就是输出连接输入罢了,常规操作。
    最后再附上一个Transformer的代码实现,读者有兴趣可以跟着自己复现一下Transformer模型的代码。
       package main

       import (
           "log"
           "sync"
       )

       func init() {
           log.SetFlags(log.Lshortfile)
       }
       func main() {
           lock := sync.Mutex{}

           //Go 1.18 新增,是一种非阻塞模式的取锁操作。当调用 TryLock() 时,
           //该函数仅简单地返回 true 或者 false,代表是否加锁成功
           //在某些情况下,如果我们希望在获取锁失败时,并不想停止执行,
           //而是可以进入其他的逻辑就可以使用TryLock()
           log.Println("TryLock:", lock.TryLock())
           //已经通过TryLock()加锁,不能再次加锁
           lock.Lock()

       }

  • 16、谷景电子贴片电感在智能电梯领域应用取得新进展
    16、谷景电子贴片电感在智能电梯领域应用取得新进展
  • [完结19章]SpringBoot开发双11商品服务系统教程下载
    如何使用SpringBoot开发一款关于双11商品服务的系统?今天就给大家说道说道,希望对大家的学习有所帮助!
    1.什么是SpringBoot?
    Spring 的诞⽣是为了简化 Java 程序的开发的,⽽ Spring Boot 的诞⽣是为了简化 Spring 程序开发的。
    Spring Boot是由Pivotal团队提供的基于Spring的框架,该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。Spring Boot集成了绝大部分目前流行的开发框架,就像Maven集成了所有的JAR包一样,Spring Boot集成了几乎所有的框架,使得开发者能快速搭建Spring项目。
    2.SpringBoot的优点
    快速集成框架,Spring Boot 提供了启动添加依赖的功能,⽤于秒级集成各种框架。
    内置运⾏容器,⽆需配置 Tomcat 等 Web 容器,直接运⾏和部署程序。
    快速部署项⽬,⽆需外部容器即可启动并运⾏项⽬。
    可以完全抛弃繁琐的 XML,使⽤注解和配置的⽅式进⾏开发。
    ⽀持更多的监控的指标,可以更好的了解项⽬的运⾏情况

    后端配置
    1.1创建Springboot工程
    打开idea->file->new->project
    选择spring Initializer进行配置,java版本选择8,点击next
    - internal 应用代码
        - controllers 控制器模块
          - admin 后端控制器
          - front 前端控制器
        - listen redis监听器
        - models 模型模块
        - service 服务模块
          - product_serive 商品服务
          - wechat_menu_serive 微信公众号菜单服务
          ......
    - conf 公共配置
      -config.yml yml配置文件
      -config.go 配置解析,转化成对应的结构体
      
    - middleware 中间件
        - AuthCheck.go  jwt接口权限校验
    - cors.go 跨域处理
    ......
    - pkg 程序应用包
      - app
      - base
      - casbin
      - jwt
      - qrcode
      - wechat
      .....
    - routere 路由
    - logs 日志存放
    - runtime 资源目录
    首先,我仔细分析了需求,并且根据业务逻辑设计了合适的接口。
    对于多表关联查询,我使用了MyBatis的注解来编写SQL语句,并通过@One和@Many等注解来实现结果集的映射。
    对于数据分页,我使用了MyBatis-Plus提供的Page对象,并结合相关方法来实现数据分页查询。
    2. 上课中的优秀项目
    在课堂上,我完成了一个优秀的项目,主要是学生实体类的增删改查功能。通过这个项目,我巩固了对Spring Boot框架的理解和掌握。
    具体实现如下:
    //初始化redis
    err := cache.InitRedis(cache.DefaultRedisClient, &redis.Options{
    Addr:        global.CONFIG.Redis.Host,
    Password:    global.CONFIG.Redis.Password,
    IdleTimeout: global.CONFIG.Redis.IdleTimeout,
    }, nil)
    if err != nil {
    if err != nil {
    global.LOG.Error("InitRedis error ", err, "client", cache.DefaultRedisClient)
    panic(err)
    }
    panic(err)
    }

    //初始化mysql
    err = db.InitMysqlClient(db.DefaultClient, global.CONFIG.Database.User,
    global.CONFIG.Database.Password, global.CONFIG.Database.Host,
    global.CONFIG.Database.Name)
    if err != nil {
    global.LOG.Error("InitMysqlClient error ", err, "client", db.DefaultClient)
    panic(err)
    }
    global.Db = db.GetMysqlClient(db.DefaultClient).DB

    开发步骤
    SpringBoot 开发起来特别简单,分为如下几步:
    创建新模块,选择Spring初始化,并配置模块相关基础信息
    选择当前模块需要使用的技术集
    开发控制器类
    运行自动生成的Application类
    知道了 SpringBoot 的开发步骤后,接下来我们进行具体的操作
    shutdown.NewHook().Close(
    //关闭http server
    func() {
    ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
    defer cancel()
    if err := server.Shutdown(ctx); err != nil {
    logging.Error("http server shutdown err", err)
    }
    },

    func() {
    //关闭kafka producer(特别是异步生产者,强制关闭会导致丢消息)
    if err := mq.GetKafkaSyncProducer(mq.DefaultKafkaSyncProducer).Close(); err != nil {
    logging.Error("kafka shutdown err", err)
    }
    },
    func() {
    //关闭mysql
    if err := db.CloseMysqlClient(db.DefaultClient); err != nil {
    logging.Error("mysql shutdown err", err)
    }
    },
    func() {
    //关闭redis
    if err := cache.GetRedisClient(cache.DefaultRedisClient).Close(); err != nil {
    logging.Error("redis shutdown err", err)
    }
    },
    )
    //也可以自己实现优雅关闭
    //signals := make(chan os.Signal, 0)
    //signal.Notify(signals, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
    //s := <-signals
    //global.LOG.Warn("shop receive system signal:", s)
    //ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
    //defer cancel()
    //err := server.Shutdown(ctx)
    //if err != nil {
    // global.LOG.Error("http server error", err)
    //}
    //mq.GetKafkaSyncProducer(mq.DefaultKafkaSyncProducer).Close()

    选择 Spring Initializr ,用来创建 SpringBoot 工程
    以前我们选择的是 Maven ,今天选择 Spring Initializr 来快速构建 SpringBoot 工程。而在 Module SDK 这一项选择我们安装的 JDK 版本。
    type StoreProduct struct {
    Image        string         `json:"image" valid:"Required;"`
    SliderImage  string         `json:"slider_image" valid:"Required;"`
    StoreName    string         `json:"store_name" valid:"Required;"`
    StoreInfo    string         `json:"store_info" valid:"Required;"`
    Keyword      string         `json:"keyword" valid:"Required;"`
    CateId       int            `json:"cate_id" valid:"Required;"`
    ProductCate  *StoreCategory `json:"product_cate" gorm:"foreignKey:CateId;association_autoupdate:false;association_autocreate:false"`
    Price        float64        `json:"price" valid:"Required;"`
    VipPrice     float64        `json:"vip_price" valid:"Required;"`
    OtPrice      float64        `json:"ot_price" valid:"Required;"`
    Postage      float64        `json:"postage" valid:"Required;"`
    UnitName     string         `json:"unit_name" valid:"Required;"`
    Sort         int16          `json:"sort" valid:"Required;"`
    Sales        int            `json:"sales" valid:"Required;"`
    Stock        int            `json:"stock" valid:"Required;"`
    IsShow       *int8          `json:"is_show" valid:"Required;"`
    IsHot        *int8          `json:"is_hot" valid:"Required;"`
    IsBenefit    *int8          `json:"is_benefit" valid:"Required;"`
    IsBest       *int8          `json:"is_best" valid:"Required;"`
    IsNew        *int8          `json:"is_new" valid:"Required;"`
    Description  string         `json:"description" valid:"Required;"`
    IsPostage    *int8          `json:"is_postage" valid:"Required;"`
    GiveIntegral int            `json:"give_integral" valid:"Required;"`
    Cost         float64        `json:"cost" valid:"Required;"`
    IsGood       *int8          `json:"is_good" valid:"Required;"`
    Ficti        int            `json:"ficti" valid:"Required;"`
    Browse       int            `json:"browse" valid:"Required;"`
    IsSub        *int8          `json:"is_sub" valid:"Required;"`
    TempId       int64          `json:"temp_id" valid:"Required;"`
    SpecType     int8           `json:"spec_type" valid:"Required;"`
    IsIntegral   *int8          `json:"isIntegral" valid:"Required;"`
    Integral     int32          `json:"integral" valid:"Required;"`
    BaseModel
    }

    //定义商品消息结构
    type ProductMsg struct {
    Operation string `json:"operation"`
    *StoreProduct
    }
    切换web服务器
    现在我们启动工程使用的是 tomcat 服务器,那能不能不使用 tomcat 而使用 jetty 服务器,jetty 在我们 maven 高级时讲 maven 私服使用的服务器。而要切换 web 服务器就需要将默认的 tomcat 服务器给排除掉,怎么排除呢?使用 exclusion 标签
    func (e *StoreProductController) Post(c *gin.Context) {
    var (
    dto  dto2.StoreProduct
    appG = app.Gin{C: c}
    )
    httpCode, errCode := app.BindAndValid(c, &dto)
    if errCode != constant.SUCCESS {
    appG.Response(httpCode, errCode, nil)
    return
    }
    productService := product_service.Product{
    Dto: dto,
    }
    model, err := productService.AddOrSaveProduct()
    if err != nil {
    appG.Response(http.StatusInternalServerError, constant.FAIL_ADD_DATA, nil)
    return
    }

    //发消息队列
    defer func() {
    operation := product.OperationCreate
    if dto.Id > 0 {
    operation = product.OperationUpdate
    }
    productMsg := models.ProductMsg{
    operation,
    &model,
    }
    msg, _ := json.Marshal(productMsg)
    p, o, e := mq.GetKafkaSyncProducer(mq.DefaultKafkaSyncProducer).Send(&sarama.ProducerMessage{
    Topic: product.Topic,
    Key:   mq.KafkaMsgValueStrEncoder(strconv.FormatInt(dto.Id, 10)),
    Value: mq.KafkaMsgValueEncoder(msg),
    },
    )
    if e != nil {
    global.LOG.Error("send product msg error ", e, "partition :", p, "offset :", o, "id :", dto.Id)
    }
    }()

    appG.Response(http.StatusOK, constant.SUCCESS, nil)

    }


  • RadarSensors_ARS408-21_cn数据手册
    RadarSensors_ARS408-21_cn数据手册
  • 基于单片机的TFT-LCD液晶显示控制芯片选型表
    基于单片机的TFT-LCD液晶显示控制芯片选型表
  • 14、小电流贴片共模电感更换需要注意些什么.
    14、小电流贴片共模电感更换需要注意些什么.
  • Wayking RadarSensors_LRR7710_中英文产品手册
    Wayking RadarSensors_LRR7710_中英文产品手册
  • 基于单片机的工业级液晶显示控制芯片
    TFT-LCD液晶显示控制芯片RA8889ML3N的优势:
    低功耗及功能强大:这款芯片最大支持分辨率为1366x2048,内置128Mb SDRAM,可为内容显示进行快速刷新,同时内置视频解码单元,支持JPEG/AVI硬解码播放,为普通单片机实现视频播放提供可能。
    支持多种接口:RA8889ML3N支持MCU端的8080/6800 8/16-bit 非同步并列接口和3/4线SPI及IIC串列接口,以及最大驱动1366x800分辨率的TFT LCD。
    显示功能强大:RA8889ML3N提供多段的显示记忆体缓冲区段,支持多图层功能,并提供画中画(PIP)、支持透明度控制与显示旋转镜像等显示功能。
    应用范围广:这款芯片广泛应用于自动化控制设备、电力监测控制、测量检测仪器仪表、电教设备、智能家电、医疗检测设备、车用仪表及工控自动化等领域。
  • XPM52C规格书 65W USB PD 多协议降压芯片
    XPM52C 是一款集成同步开关的降压转换器,支持多种输出快充协议、支持 USB Type-C 和 PD 等多种快充协议,包括 USB Type-C 和 PD 协议,高通 QC2.0/3.0/3.0+,华 为 FCP/SCP/HVSCP,VOOC 2.0/4.0 协议,联发科 PE,三星 AFC,USB BC1.2 DCP 以及 Apple 2.4A 充电规范,为车载充电器、各种快充适配器、智能排插等供电设备提供完 整的解决方案。
  • 12、如何挑选立式磁棒电感厂家
    12、如何挑选立式磁棒电感厂家
  •    本文介绍在ALPS平台上进行SSL测试的内容和方法   什么是SSL SSL全称是Secure Sockets Layer,指安全套接字协议,为基于TCP的应用层协议提供安全连接;SSL介于TCP/IP协议栈的第四层和第五层之间,广泛用于电子商务、网上银行等。 SSL协议有三个版本,其中SSL2.0和3.0曾被广泛使用,其中SSLv3.0自1996提出并得到大规模应用成为了事实上的标准,在2015年才被弃用。1999年,IETF收纳了SSLv3.0并
    信而泰市场部 2023-11-30 15:08 102浏览
  •    电源连接器的插针遭受损坏的情况非常普遍,这种故障会让连接器的电流传输受到影响,进而影响设备的正常使用,那是什么因素导致电源连接器的插针遭到损坏呢?下面Amass将为您分析其中的原因。   1、应用环境高温 1. 在高温环境下,电源连接器插针易受腐蚀影响,形成氧化层,损失接触压力,甚至可能发生接头烧损情况。对于这种环境,电源连接器需要具备耐高温性能,不仅需满足环境温度要求,还须考虑其在工作状态下的热量散发。  
    艾迈斯电子 2023-11-30 16:33 129浏览
  • 听力危机不可不慎,助听器市场的发展概况根据世界卫生组织WHO于2021年所发布的世界听力报告(World report on hearing)统计,全球目前有20%左右的听损人口;其中「轻度」与「中度」听损人口就占了大约15亿人左右。台湾方面,根据2021年卫生福利部统计处的数据显示,台湾则约有12万人有听力损失的问题,其中更有高达56% (约71,543人)确诊为轻度听损。足以看出听力受损问题已逐渐成为全球新兴的健康议题。听力损失的成因及轻重程度因人而异,但无论如何,或多或少都会影响到我们的日
    百佳泰测试实验室 2023-11-30 17:26 118浏览
  • 高低温探针台是一种用于材料科学、物理、化学等领域的实验设备,主要用于在高温和低温环境下对材料进行各种实验和研究。下面是高低温探针台的工作原理。工作原理是将样品放置在加热和冷却组件上,然后使用各种测量仪器对其进行实验和测量。具体来说,其工作流程如下:将样品放置在加热和冷却组件上;启动加热系统,将样品加热到所需的温度;启动制冷系统,将冷却组件降温到所需的温度;通过各种测量仪器对样品进行实验和测量;记录实验数据并进行分析和处理;结束实验后,关闭加热和制冷系统,并解除真空状态,取出样品。总之,高低温探针
    锦正茂科技 2023-12-01 14:50 101浏览
  •     按照 IPC术语,连接盘/Land 是指一块导体,通常用于连接和/或固定元器件的导电部分。    为了增强孔的机械强度,所有的金属化孔或者镀覆孔,在穿过每一层铜箔时,都应该有连接盘,连接盘的形状不限。前面提过的孔环也是连接盘的一种形式。在允许的条件下,孔环和连接盘的尺寸都要尽量大一些。    前面提到过,铜层图案(连接盘)和孔是在不同的工序制作的。由于加工公差的存在,用常见的圆形连接盘和圆孔来说,并不能保证孔和连接盘保持精确的同
    电子知识打边炉 2023-11-30 21:32 146浏览
  • 在电力系统中,过电压保护器是一种重要的设备,它对电力设备的安全运行具有重要的作用。下面我们来了解一下过电压保护器的基本结构。过电压保护器通常由三个主要部分组成:间隙、非线性元件和触发器。1. 间隙:间隙是过电压保护器的基本结构之一,它是由两个金属电极组成的,通常采用球形或棒形结构。间隙的间距通常在几毫米到几厘米之间,它能够承受一定的电压,并在过电压条件下进行放电。2. 非线性元件:非线性元件是过电压保护器的另一个重要组成部分。它是一种特殊的电阻器,能够在高电压下呈现出非线性的特性。当电压超过一定
    保定众邦电气 2023-11-30 14:49 173浏览
  • 前言 在网络部署之后和业务开展之前,运营商迫切希望了解当前网络的性能状态,以便为商业规划和业务推广提供必要的基础数据支持。因此,高可靠性和高精确度的性能测试方法对于运营商评判网络性能的优劣,显得尤为重要,而RFC 2544等传统测试标准已不足于鉴定当今的服务等级协议(SLA)。SLA是服务提供商(如ISP)及其最终用户之间的协议,它规定以太网服务的开通或验证必须进行测量,且必须达到SLA的规范要求。目前,对以太网服务进行测试和故障诊断的最佳选择无疑是ITU-T Y.1564标准。 &
    信而泰市场部 2023-11-30 15:06 90浏览
  • By Toradex胡珊逢 简介 双屏显示在显示设备中有着广泛的应用,可以面向不同群体展示特定内容。文章接下来将使用 Verdin iMX8M Plus 的 Arm 计算机模块演示如何方便地在 Toradex 的 Linux BSP 上实现在两个屏幕上显示独立的 Qt 应用。 硬件介绍 软件配置 Verdin iMX8M Plus 模块使用 Toradex Multimedia Reference Image V6.4.0 版本,其包含 Qt5.15 相关运行环境。默认系统中已经使
    hai.qin_651820742 2023-12-01 11:53 117浏览
  • 印刷部分 这本书印刷和普通书籍不太一样,类似笔记本的手写体印刷和笔记的网格,有亲近感和新鲜感内容部分 分为通信工程 ;传感器工程;磁传感器工程;太阳电池功能几大部分通信电路是一种用于传输信息的电子电路,可以用于无线通信、有线通信和网络通信等各种通信系统中。传感器电路则是用于感知和测量环境参数的电路,可以探测光、温度、压力、湿度、运动等各种物理量。在学习通信电路方面,可能会接触到模拟通信电路和数字通信电路。模拟通信电路主要涉及模拟信号的传输和处理,如调制解调、信号放大、滤波等。数字通信电路则涉及数
    陇南有只大花猫 2023-11-30 19:01 198浏览
  • 随着汽车电子进入电动化+智能网联的时代,新能源、车联网、智能化、电动化四个领域带来了CAN数据的需求,企业车队管理需要数据,汽车运营需要数据,改装、解码、匹配工具打造需要数据,现在就连简单的LED汽车照明控制,也需要匹配数据。这一切,逃脱不了CAN、LIN、SENT、BSD、MOST各种协议下,不同ECU控制单元在不同年份,不同款式下的数据,可以这么说,在新能源这个前提下,我们要做的工作和要做的事情可能要更为复杂、多变。 前日,我拿出一份13年左右丰田的CAN协议,里边包括车灯控制、车
    lauguo2013 2023-11-30 15:45 109浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦