-
上一篇:【Go实现】实践GoF的23种设计模式:SOLID原则简单的分布式应用系统(示例代码工程):https://github.com/ruanrunxue/Practice-Design-Pattern–Go-Implementation简述GoF 对单例模式(Singleton)的定义如下:Ensure a class only has one instance, and provide a global point of access to it.也即,保证一个类只有一个实例,并且为它提供一个全局访问点。在程序设计中,有些对象通常只需要一个共享的实例,比如线程池、全局缓存、对象池等。实现共享实例最简单直接的方式就是全局变量。但是,使用全局变量会带来一些问题,比如:客户端程序可以创建同类实例,从而无法保证在整系统上只有一个共享实例。难以控制对象的访问,比如想增加一个“访问次数统计”的功能就很难,可扩展性较低。把实现细节暴露给客户端程序,加深了耦合,容易产生霰弹式修改。对这种全局唯一的场景,更好的是使用单例模式去实现。单例模式能够限制客户端程序创建同类实例,并且可以在全局访问点上扩展或修改功能,而不影响客户端程序。但是,并非所有的全局唯一都适用单例模式。比如下面这种场景:考虑需要统计一个API调用的情况,有两个指标,成功调用次数和失败调用次数。这两个指标都是全局唯一的,所以有人可能会将其建模成两个单例SuccessApiMetric和FailApiMetric。按照这个思路,随着指标数量的增多,你会发现代码里类的定义会越来越多,也越来越臃肿。这也是单例模式最常见的误用场景,更好的方法是将两个指标设计成一个对象ApiMetric下的两个实例ApiMetic success和ApiMetic fail。那么,如何判断一个对象是否应该被建模成单例?通常,被建模成单例的对象都有“中心点”的含义,比如线程池就是管理所有线程的中心。所以,在判断一个对象是否适合单例模式时,先思考下,是一个中心点吗?UML结构代码实现根据单例模式的定义,实现的关键点有两个:限制调用者直接实例化该对象;为该对象的单例提供一个全局唯一的访问方法。对于 C++ / Java 而言,只需把对象的构造函数设计成私有的,并提供一个 static 方法去访问该对象的唯一实例即可。但 Go 语言并没有构造函数的概念,也没有 static 方法,所以需要另寻出路。我们可以利用 Go 语言 package 的访问规则来实现,将单例对象设计成首字母小写,这样就能限定它的访问范围只在当前package下,模拟了 C++ / Java 的私有构造函数;然后,在当前 package 下实现一个首字母大写的访问函数,也就相当于 static 方法的作用了。示例在简单的分布式应用系统(示例代码工程)中,我们定义了一个网络模块 network,模拟实现了网络报文转发功能。network 的设计也很简单,通过一个哈希表维持了 Endpoint 到 Socket 的映射,报文转发时,通过 Endpoint 寻址到 Socket,再调用 Socket 的 Receive 方法完成转发。因为整系统只需一个 network 对象,而且它在领域模型中具有中心点的语义,所以我们很自然地使用单例模式来实现它。单例模式大致可以分成两类,“饿汉模式”和“懒汉模式”。前者是在系统初始化期间就完成了单例对象的实例化;后者则是在调用时才进行延迟实例化,从而一定程度上节省了内存。“饿汉模式”实现// demo/network/network.go package network // 1、设计为小写字母开头,表示只在network包内可见,限制客户端程序的实例化 type network struct { sockets sync.Mapvar instancevar instance } // 2、定义一个包内可见的实例对象,也即单例 var instance = &network{sockets: sync.Map{}} // 3、定义一个全局可见的唯一访问方法 func Instance() *network { return instance } func (n *network) Listen(endpoint Endpoint, socket Socket) error { if _, ok := n.sockets.Load(endpoint); ok { return ErrEndpointAlreadyListened } n.sockets.Store(endpoint, socket) return nil } func (n *network) Send(packet *Packet) error { record, rOk := n.sockets.Load(packet.Dest()) socket, sOk := record.(Socket) if !rOk || !sOk { return ErrConnectionRefuse } go socket.Receive(packet) return nil }那么,客户端就可以通过 network.Instance() 引用该单例了:// demo/sidecar/flowctrl_sidecar.go package sidecar type FlowCtrlSidecar struct {...} // 通过 network.Instance() 直接引用单例 func (f *FlowCtrlSidecar) Listen(endpoint network.Endpoint) error { return network.Instance().Listen(endpoint, f) } ...“懒汉模式”实现众所周知,“懒汉模式”会带来线程安全问题,可以通过普通加锁,或者更高效的双重检验加锁来优化。不管是哪种方法,都是为了保证单例只会被初始化一次。type network struct {...} // 单例 var instance *network // 定义互斥锁 var mutex = sync.Mutex{} // 普通加锁,缺点是每次调用 Instance() 都需要加锁 func Instance() *network { mutex.Lock() if instance == nil { instance = &network{sockets: sync.Map{}} } mutex.Unlock() return instance } // 双重检验后加锁,实例化后无需加锁 func Instance() *network { if instance == nil { mutex.Lock() if instance == nil { instance = &network{sockets: sync.Map{}} } mutex.Unlock() } return instance }对于“懒汉模式”,Go 语言还有一个更优雅的实现方式,那就是利用 sync.Once。它有一个 Do 方法,方法声明为 func (o *Once) Do(f func()),其中入参是 func() 的方法类型,Go 会保证该方法仅会被调用一次。利用这个特性,我们就能够实现单例只被初始化一次了。type network struct {...} // 单例 var instance *network // 定义 once 对象 var once = sync.Once{} // 通过once对象确保instance只被初始化一次 func Instance() *network { once.Do(func() { // 只会被调用一次 instance = &network{sockets: sync.Map{}} }) return instance }扩展提供多个实例虽然单例模式从定义上表示每个对象只能有一个实例,但是我们不应该被该定义限制住,还得从模式本身的动机来去理解它。单例模式的一大动机是限制客户端程序对对象进行实例化,至于实例有多少个其实并不重要,根据具体场景来进行建模、设计即可。比如在前面的 network 模块中,现在新增一个这样的需求,将网络拆分为互联网和局域网。那么,我们可以这么设计:type network struct {...} // 定义互联网单例 var inetInstance = &network{sockets: sync.Map{}} // 定义局域网单例 var lanInstance = &network{sockets: sync.Map{}} // 定义互联网全局可见的唯一访问方法 func Internet() *network { return inetInstance } // 定义局域网全局可见的唯一访问方法 func Lan() *network { return lanInstance }虽然上述例子中,network 结构有两个实例,但是本质上还是单例模式,因为它做到了限制客户端实例化,以及为每个单例提供了全局唯一的访问方法。提供多种实现单例模式也可以实现多态,如果你预测该单例未来可能会扩展,那么就可以将它设计成抽象的接口,让客户端依赖抽象,这样,未来扩展时就无需改动客户端程序了。比如,我们可以 network 设计为一个抽象接口:// network 抽象接口 type network interface { Listen(endpoint Endpoint, socket Socket) error Send(packet *Packet) error } // network 的实现1 type networkImpl1 struct { sockets sync.Map } func (n *networkImpl1) Listen(endpoint Endpoint, socket Socket) error {...} func (n *networkImpl1) Send(packet *Packet) error {...} // networkImpl1 实现的单例 var instance = &networkImpl1{sockets: sync.Map{}} // 定义全局可见的唯一访问方法,注意返回值时network抽象接口! func Instance() network { return instance } // 客户端使用示例 func client() { packet := network.NewPacket(srcEndpoint, destEndpoint, payload) network.Instance().Send(packet) }如果未来需要新增一种 networkImpl2 实现,那么我们只需修改 instance 的初始化逻辑即可,客户端程序无需改动:// 新增network 的实现2 type networkImpl2 struct {...} func (n *networkImpl2) Listen(endpoint Endpoint, socket Socket) error {...} func (n *networkImpl2) Send(packet *Packet) error {...} // 将单例 instance 修改为 networkImpl2 实现 var instance = &networkImpl2{...} // 单例全局访问方法无需改动 func Instance() network { return instance } // 客户端使用也无需改动 func client() { packet := network.NewPacket(srcEndpoint, destEndpoint, payload) network.Instance().Send(packet) }有时候,我们还可能需要通过读取配置来决定使用哪种单例实现,那么,我们可以通过 map 来维护所有的实现,然后根据具体配置来选取对应的实现:// network 抽象接口 type network interface { Listen(endpoint Endpoint, socket Socket) error Send(packet *Packet) error } // network 具体实现 type networkImpl1 struct {...} type networkImpl2 struct {...} type networkImpl3 struct {...} type networkImpl4 struct {...} // 单例 map var instances = make(map[string]network) // 初始化所有的单例 func init() { instances["impl1"] = &networkImpl1{...} instances["impl2"] = &networkImpl2{...} instances["impl3"] = &networkImpl3{...} instances["impl4"] = &networkImpl4{...} } // 全局单例访问方法,通过读取配置决定使用哪种实现 func Instance() network { impl := readConf() instance, ok := instances[impl] if !ok { panic("instance not found") } return instance }典型应用场景日志。每个服务通常都会需要一个全局的日志对象来记录本服务产生的日志。全局配置。对于一些全局的配置,可以通过定义一个单例来供客户端使用。唯一序列号生成。唯一序列号生成必然要求整系统只能有一个生成实例,非常合适使用单例模式。线程池、对象池、连接池等。xxx池的本质就是共享,也是单例模式的常见场景。全局缓存…优缺点优点在合适的场景,使用单例模式有如下的优点:整系统只有一个或几个实例,有效节省了内存和对象创建的开销。通过全局访问点,可以方便地扩展功能,比如新增加访问次数的统计。对客户端隐藏实现细节,可避免霰弹式修改。缺点虽然单例模式相比全局变量有诸多的优点,但它本质上还是一个“全局变量”,还是避免不了全局变量的一些缺点:函数调用的隐式耦合。通常我们都期望从函数的声明中就能知道该函数做了什么、依赖了什么、返回了什么。使用使用单例模式就意味着,无需通过函数传参,就能够在函数中使用该实例。也即将依赖/耦合隐式化了,不利于更好地理解代码。对测试不友好。通常对一个方法/函数进行测试,我们并不需要知道它的具体实现。但如果方法/函数中有使用单例对象,我们就不得不考虑单例状态的变化了,也即需要考虑方法/函数的具体实现了。并发问题。共享就意味着可能存在并发问题,我们不仅需要在初始化阶段考虑并发问题,在初始化后更是要时刻注意。因此,在高并发的场景,单例模式也可能存在锁冲突问题。单例模式虽然简单易用,但也是最容易被滥用的设计模式。它并不是“银弹”,在实际使用时,还需根据具体的业务场景谨慎使用。与其他模式的关联工厂方法模式、抽象工厂模式很多时候都会以单例模式来实现,因为工厂类通常是无状态的,而且全局只需一个实例即可,能够有效避免对象的频繁创建和销毁。
-
【欢喜闹元宵专题活动】元宵圆圆,福利连连,游戏go~go~go~的奖品没收到。。
-
如题
-
论文题目:OntoProtein: Protein Pretraining With Gene Ontology Embedding本文作者:张宁豫(浙江大学)、毕祯(浙江大学)、梁孝转(浙江大学)、程思源(浙江大学)、洪浩森(浙江大学)、邓淑敏(浙江大学)、连佳长(浙江大学)、张强(浙江大学)、陈华钧(浙江大学)发表会议:ICLR 2022论文链接:https://www.zhuanzhi.ai/paper/6e757d23f8b6b16cb91cdcad6f124b3c代码链接:https://github.com/zjunlp/OntoProtein欢迎转载,转载请注明出处一、引言近年来,预训练模型以强大的算法效果,席卷了自然语言处理为代表的各大AI榜单与测试数据集。与自然语言类似,蛋白质的一级结构具有序列特性,这为将语言预训练模型引入蛋白质表示提供了有利条件。然而,蛋白质本质上不同于自然语言文本,其包含了大量预训练目标较难习得的生物学知识。事实上,人类科学家已经积累了海量的关于蛋白质结构功能的生物学知识。那么如何利用这些知识促进蛋白质预训练呢?本文将介绍被ICLR2022录用的新工作:OntoProtein,其提出一种新颖的融入知识图谱的蛋白质预训练方法。 二、蛋白质预训练 蛋白质是控制生物和生命本身的基本大分子,对蛋白质的研究有助于理解人类健康和发展疾病疗法。蛋白质包含一级结构,二级结构和三级结构,其中一级结构与语言具有相似的序列特性。受到自然语言处理预训练模型的启发,诸多蛋白质预训练模型和工具被提出,包括MSA Transformer[1]、ProtTrans[2]、悟道 · 文溯[3]、百度的PaddleHelix等。大规模无监督蛋白质预训练甚至可以从训练语料中习得一定程度的蛋白质结构和功能。然而,蛋白质本质上不同于自然语言文本,其包含了诸多生物学特有的知识,较难直接通过预训练目标习得,且会受到数据分布影响低频长尾的蛋白质表示。为了解决这些问题,我们利用人类科学家积累的关于蛋白质结构功能的海量生物知识,首次提出融合知识图谱的蛋白质预训练方法。下面首先介绍知识图谱构建的方法。三、基因知识图谱我们通过访问公开的基因本体知识图谱“Gene Ontology(简称Go)”,并将其和来自Swiss-Prot数据库的蛋白质序列对齐,来构建用于预训练的知识图谱ProteinKG25,该知识图谱包含4,990,097个三元组, 其中4,879,951个蛋白质-Go的三元组,110,146 个Go-Go三元组,并已全部开放供社区使用。如下图所示,基于“结构决定功能”的思想,如果在蛋白质预训练过程中显式地告诉模型什么样的结构具备什么样的功能,显然能够促进如蛋白质功能预测、蛋白质交互预测等任务的效果。四、融入基因知识图谱的蛋白质预训练:OntoProtein基于构建好的知识图谱,我们设计了一个特殊的蛋白质预训练模型OntoProtein。注意到在预训练输入中包含两种不同的序列:蛋白质序列和描述蛋白质功能、生物过程等的文本描述信息。因此,我们采取两路不同的编码器。对蛋白质序列我们采用已有的蛋白质预训练模型ProtBert进行编码,对文本序列我们采用BERT进行编码。为了更好地进行预训练和融合三元组知识信息,我们采用了两个优化目标。首先是传统的掩码语言模型目标,我们通过随机Mask序列中的一个Token并预测该Token。其次是三元组知识增强目标,我们通过类似知识图谱嵌入学习的方式来植入生物学三元组知识,如下公式所示:注意到这里的事实知识分为两类不同的三元组,分别是Go-Go和蛋白质-Go,因此我们提出一种知识增强的负采样方法,以获得更有代表性的负样本提升预训练效果,采样方式如下 :五、实验分析我们在蛋白质测试基准TAPE,以及蛋白质蛋白质交互、蛋白质功能预测(我们参考CAFA竞赛构建了一个新的蛋白质功能预测数据集)上进行了实验。如下表所示,可以发现融合知识图谱的蛋白质预训练方法在一定程度上取得了较好或可比的性能。特别地,我们的方法没有使用同源序列比对(MSA),因此较难超越基于MSA Transformer的方法。详细的实验结果请参见论文,我们会在近期将预训练模型整理并发布到Huggingface上供社区使用。六、小结与展望当下蓬勃兴起的 AI for Science 正在促使以数据驱动的开普勒范式和以第一性原理驱动的牛顿范式的深度融合。基于“数据与知识双轮驱动”的学术思想,我们在本文中首次提出了融合知识图谱的蛋白质预训练方法OntoProtein,并在多个下游任务中验证了模型的效果。在未来,我们将维护好OntoProtein以供更多学者使用,并计划探索融合同源序列比对的知识图谱增强预训练方法以实现更优性能。[1] MSA Transformer ICML2021 [2] ProtTrans: Towards Cracking the Language of Life’s Code Through Self-Supervised Learning TPAMI2021 [3] Modeling Protein Using Large-scale Pretrain Language Model 2021
-
原文链接:https://blog.csdn.net/csdndevelopers/article/details/122941245作为Unix的研发者与传奇代码“Hello World”的发明者,普林斯顿大学计算机科学系教授布莱恩·克尼汉(Brian W. Kernighan)是编程界的传奇人物。他曾参与创造了AMPL(数学编程语言)和AWK(文本处理工具),也曾和C语言之父丹尼斯·里奇(Dennis MacAlistair Ritchie)共同编写《C程序设计语言》(The C Programming Language)。不仅如此,据调查,Brian W. Kernighan竟在1972年7月18日首次提交Go代码。commit 7d7c6a97f815e9279d08cfaea7d5efb5e90695a8Author: Brian Kernighan <bwk>Date: Tue Jul 18 19:05:45 1972 -0500 hello, world R=ken DELTA=7 (7 added, 0 deleted, 0 changed)diff --git a/src/pkg/debug/macho/testdata/hello.b b/src/pkg/debug/macho/testdata/hello.bnew file mode 100644index 0000000000..05c4140424--- /dev/null+++ b/src/pkg/debug/macho/testdata/hello.b@@ -0,0 +1,7 @@+main( ) {+ extrn a, b, c;+ putchar(a); putchar(b); putchar(c); putchar('!*n');+} +a 'hell';+b 'o, w';+c 'orld';在接下来的十多年中,布莱恩仍在不断进行修改:1974年1月20日01:02:03:布莱恩提交了convert to C,将B语言的Hello World改为C语言实现;1988年4月1日02:02:04:提交convert to Draft-Proposed ANSI C,将HelloWorld改为草案中提出的ANSI C实现;1988年4月1日02:03:04:提交last-minute fix: convert to ANSI C,最后修改,改为ANSI C实现。1988年,布莱恩团队决定暂停更新。直到20年后的2007年9月,罗伯特·格瑞史莫(Robert Griesemer),罗勃·派克(Rob Pike)和肯·汤普逊(Ken Thompson)开始设计Go,提交了Go spec starting point。直到现在,这些早期提交的文件(即最终的ANSI C 版本)仍保留在Go repo中。【参考资料】https://repography.com/blog/go-first-commithttps://github.com/golang/go/commit/0bb0b61d6a85b2a1a33dcbc418089656f2754d32https://github.com/golang/go/commit/0744ac969119db8a0ad3253951d375eb77cfce9ehttps://github.com/golang/go/commit/d82b11e4a46307f1f1415024f33263e819c222b8
-
老板,能不能上个JBL GO2 音乐金砖,家里迫切需要一个。谢谢了。
-
编译openGauss-prometheus-exporter 有要求go必须是多少版本以上的吗?
-
go语言有很多的插件来编译程序 其中最为好的就是goland 转载一篇关于安装goland的文章希望大家喜欢原文链接:https://blog.csdn.net/weixin_42809940/article/details/82423171go语言环境安装下载地址:https://golang.google.cn/dl/goland软件安装下载地址:http://www.jetbrains.com/go/download/#section=windowsgoland许可证认证码可以到网站http://idea.lanyus.com/查询认证码。github 上clone项目配置系统的环境变量GOPATH为任意一个目录,用于存放src下的package目录再然后把项目放入GOPTH目录下的src目录下使用go get 安装各种包golang.org/x/net 安装方法为了使包的导入方式不变,我们需要在src目录下面构造目录结构$mkdir -p $GOPATH/src/golang.org/x/$cd $GOPATH/src/golang.org/x/$git clone https://github.com/golang/net.git net$go install net执行go install之后没有提示,就说明安装好了。windows安装go-sqlite3失败,提示找不到gccwindows安装go-sqlite3失败,提示找不到gcc go get github.com/mattn/go-sqlite3时失败,提示exec: “gcc”: executable file not found in %PATH%,是因为没有安装gcc。 去http://tdm-gcc.tdragon.net/download下载一个,32位windows下载 tdm-gcc-4.8.1-3.exe,64位下载 tdm64-gcc-4.8.1-3.exe注:为保证能够成功编译,建议安装所有的包。安装完成以后,配置环境变量path中添加gcc安装目录,C:\TDM-GCC-64\bin运行go get 指令 提示unrecognized import path运行指令如下:go get google.golang.org/grpc错误提示:package google.golang.org/grpc: unrecognized import path "google.golang.org/grpc" (https fetch: Get https://google.golang.org/grpc?go-get=1: dial tcp 74.125.28.14:443: i/o timeout)解决方法:1、建立相关文件夹mkdir -p $GOPATH/src/google.golang.org/2、命令行打开文件夹cd $GOPATH/src/google.golang.org3、从Github上克隆其他的仓库 git clone https://github.com/Agzs/grpc grpc4、 安装仓库cd $GOPATH/src/go install google.golang.org/grpc5、 结束最后运行成功。
-
【功能模块】ECS鲲鹏服务器安装go1.15.3出现cannot execute binary file: Exec format error【操作步骤&问题现象】1、下载Go软件包wget https://kunpeng-ip.obs.cn-north-4.myhuaweicloud.com/%E5%AE%9E%E9%AA%8C%E8%B5%84%E6%BA%90/3.2%20Go%E8%AF%AD%E8%A8%80%E4%BB%A3%E7%A0%81%E7%A7%BB%E6%A4%8D/go1.15.3.linux-amd64.tar.gz2、解压到指定目录tar -C /usr/local -xzvf go1.15.3.linux-amd64.tar.gz3、添加环境变量export PATH=$PATH:/usr/local/go/binexport GOROOT=/usr/local/goexport GOPATH=$HOME/goexport PATH=$PATH:$GOPATH/bin4、验证Go安装cp /usr/local/go/bin/go /usr/bin/gogo version【截图信息】【日志信息】(可选,上传日志内容或者附件)标签:弹性云服务器 ECS 鲲鹏
-
# Kubernetes 使用secret和--device > > k8s 的版本 v1.17 ; docker 版本 18.09.0 ### 1. 创建secret 用于存放预共享秘钥 - 参考文档:[Kubernetes /中文文档 /Secret](https://kubernetes.io/zh/docs/concepts/configuration/secret/) https://kubernetes.io/zh/docs/concepts/configuration/secret/ - 我这儿给出 通过yaml 文件创建 Opaque 类型的 Secret 的实例参考 ```yaml apiVersion: v1 kind: Secret metadata: name: mysecret # 创建secret的名字 namespace: ming-feng # 根据自己的需要设置使用哪个命名空间, 可以不用设置 type: Opaque data: pwd: MTIzNDU2Cg== # value 秘钥:123456 转 base64 的值 ``` - 创建secret ```sh root@ubuntu:~/mingfeng/secret# kubectl apply -f sercet.yaml secret/mysecret created root@ubuntu:~/mingfeng/secret# kubectl get secret -n ming-feng NAME TYPE DATA AGE default-token-lng4k kubernetes.io/service-account-token 3 2m33s mysecret Opaque 1 27s ``` ### 2. Kubernetes 使用 --device - Kubernetes支持`--device`问题在社区上讨论了很久,当前的解决方案有两种 - 1、通过加上 **privileged: true** 是容器拥有物理机上所有设备的使用权限 - 但是从安全角度考虑,使用 privileged:true 可能并不理想 - 2、**device plugins机制来注册要访问的设备,典型的如GPU** - 以下我通过 device plugins 方式来进行演示 #### 2.1 device plugins 的使用 - device plugins 接口的介绍 以下给出k8s 设备插件的接口信息和原理介绍 感兴趣的朋友可以仔细研读一下,自己制作插件 - 参考文档 [Kubernetes 文档/设备插件](https://kubernetes.io/zh/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/) https://kubernetes.io/zh/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/ - 原理介绍 [Kubernetes|中文社区](https://www.kubernetes.org.cn/4391.html) https://www.kubernetes.org.cn/4391.html - 插件介绍 - /dev下有很多的设备,每个设备都写一个插件会很麻烦,有大佬开源了个k8s-hostdev-plugin,可以解决大部分插件问题 - github地址:**[k8s-hostdev-plugin](https://github.com/bluebeach/k8s-hostdev-plugin)** - 码云地址:**[k8s-hostdev-plugin](https://gitee.com/leexiali/k8s-hostdev-plugin)** - 编译 k8s-hostdev-plugin 插件 (之前没用过 go 纯小白 踩了很多坑, 所以以下安装步骤仅供参考) > > linux ubuntu 环境上安装 - 直接基于插件的 README.md Build 说明 编译出现了些问题, 所以我采用了 手动编译的方式 - 1,插件是基于go 语言编译的所以需要安装go环境 - 设置代理 - go env -w GOPROXY=https://goproxy.cn,direct - 2,通过 go env 找到 GOPATH 然后在 GOPATH 新建src目录,将git 下载下来的代码放到该目录下 - 编译 - 第一步 go mod init 初始化后会在当前目录下生成 go.mod 文件 ```sh root@ubuntu:~/go/src/k8s-hostdev-plugin-master# go mod init go: creating new go.mod: module k8s.io/k8s-hostdev-plugin go: converting vendor/vendor.json: stat golang.org/x/tools/go/loader@: golang.org/x/tools/go/loader@: ... 【下载中。。。 耗时很长 耐心等待】 go: copying requirements from vendor/vendor.json go: to add module requirements and sums: go mod tidy ``` - 第二步 go mod tidy - 第一次报错 以及解决方案 ```sh root@ubuntu:~/go/src/k8s-hostdev-plugin-master# go mod tidy go: finding module for package github.com/Sirupsen/logrus go: finding module for package github.com/fsnotify/fsnotify go: finding module for package github.com/pmezard/go-difflib/difflib ... go: k8s.io/k8s-hostdev-plugin imports github.com/Sirupsen/logrus: github.com/Sirupsen/logrus@v1.8.1: parsing go.mod: module declares its path as: github.com/sirupsen/logrus but was required as: github.com/Sirupsen/logrus 原因是因为 模块的 首字母发生了变化 ``` - 解决 go.mod 文件后面加上 一个 replace ```sh root@ubuntu:~/go/src/k8s-hostdev-plugin-master# echo "replace github.com/Sirupsen/logrus v1.4.1 => github.com/sirupsen/logrus v1.4.1" >> go.mod root@ubuntu:~/go/src/k8s-hostdev-plugin-master# cat go.mod module k8s.io/k8s-hostdev-plugin go 1.17 require ( github.com/davecgh/go-spew v1.1.1 github.com/golang/protobuf v1.2.1-0.20180917234931-6e3d092c77c3 golang.org/x/crypto v0.0.0-20181015023909-0c41d7ab0a0e golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3 golang.org/x/sys v0.0.0-20181023152157-44b849a8bc13 google.golang.org/genproto v0.0.0-20180912233945-5a2fd4cab2d6 ) replace github.com/Sirupsen/logrus v1.4.1 => github.com/sirupsen/logrus v1.4.1 ``` - 第二次 运行报错 ```shell root@ubuntu:~/go/src/k8s-hostdev-plugin-master# go mod tidy ... k8s.io/k8s-hostdev-plugin imports k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1beta1: module k8s.io/kubernetes@latest found (v1.23.1), but does not contain package k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1beta1 原因是 $GOPATH/pkg/mod/k8s.io/kubernetes@v1.23.1 下面没有 deviceplugin/v1beta1 ``` - 解决 查了很多资料没有找到合适的办法, 就尝试 将vendor目录下的文件复制到 $GOPATH 下面 ```shell root@ubuntu:~/go/src/k8s-hostdev-plugin-master# cp -rf vendor/k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin /root/go/pkg/mod/k8s.io/kubernetes@v1.23.1/pkg/kubelet/apis /root/go 是 $GOPATH 路径 ``` - 第三次 运行报错 ```sh root@ubuntu:~/go/src/k8s-hostdev-plugin-master# go mod tidy go: finding module for package google.golang.org/grpc go: finding module for package github.com/fsnotify/fsnotify go: finding module for package github.com/pmezard/go-difflib/difflib go: finding module for package k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1beta1 go: found github.com/Sirupsen/logrus in github.com/Sirupsen/logrus v1.4.1 go: found github.com/fsnotify/fsnotify in github.com/fsnotify/fsnotify v1.5.1 go: found google.golang.org/grpc in google.golang.org/grpc v1.43.0 go: found k8s.io/kubernetes/pkg/kubelet/apis/deviceplugin/v1beta1 in k8s.io/kubernetes v1.23.1 go: found github.com/pmezard/go-difflib/difflib in github.com/pmezard/go-difflib v1.0.0 go: k8s.io/kubernetes@v1.23.1 requires k8s.io/api@v0.0.0: reading k8s.io/api/go.mod at revision v0.0.0: unknown revision v0.0.0 ``` - 解决 - 原因 :在Kubernetes主仓中,也使用了公共库,不过`go.mod`文件中所有公共库版本都指定为了**v0.0.0(显然这个版本不存在)**,然后通过**Go Module的replace**机制,将版本替换为子目录 - 资料参考 [Kubernetes平台开发者小技巧](http://dockone.io/article/2434308) http://dockone.io/article/2434308 ```sh 参考资料,编写脚本 root@ubuntu:~/go/src/k8s-hostdev-plugin-master# cat get_k8s_v.sh #!/bin/sh set -euo pipefail VERSION=${1#"v"} if [ -z "$VERSION" ]; then echo "Must specify version!" exit 1 fi MODS=($( curl -sS https://raw.githubusercontent.com/kubernetes/kubernetes/v${VERSION}/go.mod | sed -n 's|.*k8s.io/\(.*\) => ./staging/src/k8s.io/.*|k8s.io/\1|p' )) for MOD in "${MODS[@]}"; do V=$( go mod download -json "${MOD}@kubernetes-${VERSION}" | sed -n 's|.*"Version": "\(.*\)".*|\1|p' ) go mod edit "-replace=${MOD}=${MOD}@${V}" done go get "k8s.io/kubernetes@v${VERSION}" # v1.23.1 可以根据 上面报错的版本填写 root@ubuntu:~/go/src/k8s-hostdev-plugin-master# /bin/bash get_k8s_v.sh v1.23.1 go get: upgraded github.com/golang/protobuf v1.2.1-0.20180917234931-6e3d092c77c3 => v1.5.2 go get: upgraded github.com/stretchr/testify v1.2.3-0.20181115233458-8019298d9fa5 => v1.7.0 go get: upgraded golang.org/x/crypto v0.0.0-20181015023909-0c41d7ab0a0e => v0.0.0-20210817164053-32db794688a5 go get: upgraded golang.org/x/net v0.0.0-20180911220305-26e67e76b6c3 => v0.0.0-20211209124913-491a49abca63 go get: upgraded golang.org/x/sys v0.0.0-20181023152157-44b849a8bc13 => v0.0.0-20210831042530-f4d43177bf5e go get: upgraded google.golang.org/genproto v0.0.0-20180912233945-5a2fd4cab2d6 => v0.0.0-20210831024726-fe130286e0e2 go get: added k8s.io/kubernetes v1.23.1 ``` - 第三步 go mod vendor - 第四步 go build -o k8s-hostdev-plugin - 生成 执行文件 k8s-hostdev-plugin - 本地测试插件是否运行正常 ```sh root@ubuntu:~/mingfeng# ./k8s-hostdev-plugin FATA[0000] Must have arg --devs , for example, --devs /dev/mem:rwm root@ubuntu:~/mingfeng# ./k8s-hostdev-plugin --devs /dev/mem:rwm config: main.HostDevicePluginConfig{DevList:[]*main.DevConfig{(*main.DevConfig)(0xc0000e4500)}} INFO[0000] Starting FS watcher. INFO[0000] Starting OS watcher. INFO[0005] Register /dev/mem success <*>{/dev/mem rwm dev_mem hostdev.k8s.io/dev_mem /var/lib/kubelet/device-plugins/dev_mem <*>{<*>{<max>} /var/lib/kubelet/device-plugins/dev_mem true {<max>}} <*>{{<max>} {<max>} map[<max>] map[<max>] true false <*>{<max>} map[<max>] <nil> <*>{<max>} <*>{<max>} {<max>} {<max>} 0 <*>{<max>} <nil>} [<*>&Device{ID:/dev/mem,Health:Healthy,}] true 0xc00011e000} ``` ### 3. 以 使用设备 /dev/fuse 为例 注册插件 - 注册插件 - 修改 k8s-hostdev-plugin 插件 提供的Dockerfile 构建镜像 ```dockerfile FROM ubuntu:18.04 # 我这儿使用了 下载好的ubuntu的镜像 COPY k8s-hostdev-plugin /usr/bin/k8s-hostdev-plugin CMD ["k8s-hostdev-plugin"] ``` - 修改注册插件 hostdev-plugin-ds.yaml 进行修改 ```yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: hostdev-device-plugin namespace: ming-feng spec: selector: matchLabels: name: hostdev-device-plugin-ds template: metadata: annotations: scheduler.alpha.kubernetes.io/critical-pod: "" labels: name: hostdev-device-plugin-ds spec: tolerations: - key: CriticalAddonsOnly operator: Exists hostNetwork: true containers: - name: hostdev image: hostdev:v1 command: [ "k8s-hostdev-plugin"] args: ["--devs", "/dev/mem:r,/dev/fuse:rwm"] # 在这儿添加用于注册的设备以及权限 # 原来的 yaml 文件中 这儿使用了 securityContext: privileged: true 特权容器 # 但经过我的验证 在挂载 /dev/fuse 时 并不需要 指定 privileged: true 特权参数 volumeMounts: - name: device-plugin mountPath: /var/lib/kubelet/device-plugins - name: dev mountPath: /dev volumes: - name: device-plugin hostPath: path: /var/lib/kubelet/device-plugins - name: dev hostPath: path: /dev ``` - 运行插件 ```shell # 创建 插件容器 root@ubuntu:~/mingfeng# kubectl create -f hostdev-plugin-ds.yaml daemonset.apps/hostdev-device-plugin created # 查看 运行情况 root@ubuntu:~/mingfeng# kubectl get all -n ming-feng NAME READY STATUS RESTARTS AGE pod/hostdev-device-plugin-v6znd 1/1 Running 0 26s NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset.apps/hostdev-device-plugin 1 1 1 1 1 <none> 26s # 删除 插件容器 root@ubuntu:~/mingfeng# kubectl delete daemonset hostdev-device-plugin -n ming-feng daemonset.apps "hostdev-device-plugin" deleted root@ubuntu:~/mingfeng# ``` ### 4. k8s 使用secret和 --device 下发容器 - 编辑 yaml 文件 ```yaml apiVersion: v1 kind: Pod metadata: name: sznp-pod namespace: ming-feng annotations: # 对应 docker run --security-opt apparmor=profile 参数 container.apparmor.security.beta.kubernetes.io/sznp-con: localhost/profile # docker run -security-opt seccomp=mount.json 参数 container.seccomp.security.alpha.kubernetes.io/sznp-con: localhost/profiles/mount.json spec: hostNetwork: true # 如果要将 secret 挂载到 /run/secret 目录下面 则 需要 设置 ServiceAccount 为false # 挂载到其他的目录则不需要, 原因是因为 ServiceAccount 会默认挂载到 /run/secret/kubernetes.io 下面 automountServiceAccountToken: false containers: - name: sznp-con image: sznp-k8s-demo:v1 securityContext: capabilities: # 对应 docker run --cap-add SYS_ADMIN add: ["SYS_ADMIN"] resources: limits: hostdev.k8s.io/dev_fuse: 1 imagePullPolicy: Never command: [ "/bin/bash", "-c"] args: [ "sleep 3600" ] volumeMounts: - name: secrets mountPath: /run/secrets volumes: - name: secrets secret: secretName: mysecret items: - key: pwd path: pwd ``` - 参数 说明 - capabilities 对应的是 --cap-add SYS_ADMIN - `--device`挂载的设备,容器内的进程通常没有权限操作,需要使用`--cap-add`开放相应的权限 - apparmor - 用于限制容器对资源的访问 - 具体的配置 参考资料 [Kubernetes文档/AppArmor](https://kubernetes.io/zh/docs/tutorials/clusters/apparmor/) https://kubernetes.io/zh/docs/tutorials/clusters/apparmor/ - seccomp - 用于限制容器的系统调用 - 具体的配置 参考资料 [Kubernetes文档/Seccomp ](https://kubernetes.io/zh/docs/tutorials/clusters/seccomp/) https://kubernetes.io/zh/docs/tutorials/clusters/seccomp/ - 运行k8s 下发容器的命名 ```sh 先运行设备插件 root@ubuntu:~/mingfeng# kubectl create -f hostdev-plugin-ds.yaml daemonset.apps/hostdev-device-plugin created 运行使用设备和secret的容器 root@ubuntu:~/mingfeng# kubectl create -f device_secret.yaml pod/sznp-pod created 查看运行情况 root@ubuntu:~/mingfeng# kubectl get all -n ming-feng NAME READY STATUS RESTARTS AGE pod/hostdev-device-plugin-5gfds 1/1 Running 0 22s pod/sznp-pod 1/1 Running 0 10s NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset.apps/hostdev-device-plugin 1 1 1 1 1 22s ``` - 进入容器里面查看 设备和secret ```sh 进入容器 root@ubuntu:~/mingfeng# kubectl exec -it sznp-pod bash -n ming-feng 查看secret root@ubuntu:/home/mf# cat /run/secrets/pwd 123456 查看 设备挂载情况 root@ubuntu:/home/mf# ll /dev/ total 4 ... crw-rw-rw- 1 root root 1, 7 Dec 29 10:45 full crw-rw-rw- 1 root root 10, 229 Dec 29 10:45 fuse drwxrwxrwt 2 root root 40 Dec 29 10:45 mqueue/ ... root@ubuntu:/home/mf# cat /sys/devices/virtual/misc/fuse/dev 10:229 # 退出容器 root@ubuntu:/home/mf# exit exit ``` - 删除下发的pod和容器 ```sh root@ubuntu:~/mingfeng# kubectl delete pod sznp-pod -n ming-feng pod "sznp-pod" deleted root@ubuntu:~/mingfeng# kubectl delete daemonset hostdev-device-plugin -n ming-feng daemonset.apps "hostdev-device-plugin" deleted root@ubuntu:~/mingfeng# ``` ### 5. 参考文档 []: https://www.cnblogs.com/dream397/p/14034632.html "Docker及Kubernetes下device使用和分析" []: https://kubernetes.io/zh/docs/home/ "Kubernetes 文档" []: http://dockone.io/article/2434308 "Kubernetes平台开发者小技巧"
-
Go语言作为一门全新的静态类型开发语言,与当前的开发语言相比具备众多令人兴奋不已的新特性。自动垃圾回收我们可以先看下不支持垃圾回收的语言的资源管理方式,以下为一小段C语言代码void foo() { char* p = new char[128]; ... // 对p指向的内存块进行赋值 func1(p); // 使用内存指针 delete[] p; } 各种非预期的原因,比如由于开发者的疏忽导致最后的delete语句没有被调用,都会引发经典而恼人的内存泄露问题。假如该函数被调用得非常频繁,那么我们观察该进程执行时,会发现该进程所占用的内存会一直疯长,直至占用所有系统内存并导致程序崩溃,而如果泄露的是系统资源的话,那么后果还会更加严重,最终很有可能导致系统崩溃。 手动管理内存的另外一个问题就是由于指针的到处传递而无法确定何时可以释放该指针所指向的内存块。假如代码中某个位置释放了内存,而另一些地方还在使用指向这块内存的指针,那么这些指针就变成了所谓的“野指针”(wild pointer)或者“悬空指针”(dangling pointer),对这些指针进行的任何读写操作都会导致不可预料的后果。 由于其杰出的效率,C和C++语言在非常长的时间内都作为服务端系统的主要开发语言,比如Apache、Nginx和MySQL等著名的服务器端软件就是用C和C++开发的。然而,内存和资源管理一直是一个让人非常抓狂的难题。服务器的崩溃十有八九就是因为不正确的内存和资源管理导致,更讨厌的是这种内存和资源管理问题即使被发现了,也很难定位到具体的错误地点,导致数程序员通宵达旦地调试程序。 这个问题在多年里被不同人用不同的方式来试图解决,并诞生了一些非常著名的内存检查工具,比如Rational Purify、Compuware BoundsChecker和英特尔的Parallel Inspector等。从设计方法的角度也衍生了类似于内存引用计数之类的方法(通常被称为“智能指针”),后续在Windows平台上标准化的COM出现的一个重要原因就是为了解决内存管理的难题。但是事实证明,这些工具和方法虽然能够在一定程度上辅助开发者,但并没法让开发者避免通宵调试这样又苦又累的工作。 到目前为止,内存泄露的最佳解决方案是在语言级别引入自动垃圾回收算法(Garbage Collection,简称GC)。所谓垃圾回收,即所有的内存分配动作都会被在运行时记录,同时任何对该内存的使用也都会被记录,然后垃圾回收器会对所有已经分配的内存进行跟踪监测,一旦发现有些内存已经不再被任何人使用,就阶段性地回收这些没人用的内存。当然,因为需要尽量最小化垃圾回收的性能损耗,以及降低对正常程序执行过程的影响,现实中的垃圾回收算法要比这个复杂得多,比如为对象增加年龄属性等,但基本原理都是如此。 自动垃圾回收在C/C++社区一直作为一柄双刃剑看待,虽然到C++0x(后命名为C++11)正式发布时,这个呼声颇高的特性总算是被加入了,但按C++之父的说法,由于C++本身过于强大,导致在C++中支持垃圾收集变成了一个困难的工作。假如C++支持垃圾收集,以下的代码片段在运行时就会是一个严峻的考验:int* p = new int; p += 10; // 对指针进行了偏移,因此那块内存不再被引用 // …… 这里可能会发生针对这块int内存的垃圾收集 …… p -= 10; // 咦,居然又偏移到原来的位置 *p = 10; // 如果有垃圾收集,这里就无法保证可以正常运行了 微软的C++/CLI算是用一种偏门的方式让C++程序员们有机会品尝一下垃圾回收功能的鲜美味道。在C/C++之后出现的新语言,比如Java和C#等,基本上都已经自带自动垃圾回收功能。 Go语言作为一门新生的开发语言,当然不能忽略内存管理这个问题。又因为Go语言没有C++这么“强大”的指针计算功能,因此可以很自然地包含垃圾回收功能。因为垃圾回收功能的支持,开发者无需担心所指向的对象失效的问题,因此Go语言中不需要delete关键字,也不需要free()方法来明确释放内存。例如,对于以上的这个C语言例子,如果使用Go语言实现,我们就完全不用考虑何时需要释放之前分配的内存的问题,系统会自动帮我们判断,并在合适的时候(比如CPU相对空闲的时候)进行自动垃圾收集工作。
-
“昇腾众智金质量奖”第四期评选结果已新鲜出炉,恭喜各位开发者!开发者所属院校指导老师交付内容获奖事迹奖品汪字全西安电子科技大学苗启广MindX 高性能预训练模型-EAST在高性能预训练模型 EAST 交付中,主动思考,对发现的问题寻求解决方案,快速闭环,提前完成了ModelArts训练、SDK&MxBase推理,高质量达成交付要求。HUAWEI WATCH FIT谭华林西安电子科技大学苗启广MindX 高性能预训练模型-Fast-SCNN在高性能预训练模型 Fast-SCNN和BRDNet 交付中,快速学习背景知识,理解项目流程,主动与支持人员积极沟通,解决问题,提前完成了ModelArts训练、SDK&MxBase推理,高质量达成交付要求。【46mm表盘】HUAWEI WATCH GT 2谭华林西安电子科技大学苗启广MindX 高性能预训练模型-BRDNet王科中科院软件所于佳耕MindX 高性能预训练模型-Inception_ResNet_v2在高性能预训练模型 Inception_ResNet_v2模型交付中,快速理解业务需求,发挥对昇腾技术栈深刻理解,以及团队历史成功交付经验的优势,在极短的时间内就完成了该模型的高质量开发交付。FreeBuds 4i 无线耳机苗玉霞中科院软件所于佳耕MindX 高性能预训练模型-MnasNet在高性能预训练模型 MnasNet 模型交付中,快速理解业务需求,发挥对昇腾技术栈深刻理解,以及团队历史成功交付经验的优势,在极短的时间内就完成了该模型的高质量开发交付。华为手环 6黄键中科院软件所于佳耕MindX 高性能预训练模型-SE-ResNet-50在高性能预训练模型 SE-ResNet-50 模型交付中,快速理解业务需求,发挥对昇腾技术栈深刻理解,以及团队历史成功交付经验的优势,在极短的时间内就完成了该模型的高质量开发交付。华为无线键盘黄纲弘重庆大学钟将MindX 高性能预训练模型-ERNIE在高性能预训练模型交付中,该同学一人负责ERNIE、EmoTect和DGU三个NLP模型,积极主动,目标明确,提前完成所负责的三个模型的ModelArts训练、SDK&MxBase推理,高质量达成交付要求。SKG-颈椎按摩器-G7黄纲弘重庆大学钟将MindX 高性能预训练模型-EmoTectSKG-颈椎按摩器-G7黄纲弘重庆大学钟将MindX 高性能预训练模型-DGU倍益康 MINI 肌肉按摩器王雯卿浙江大学梁秀波MindX 高性能预训练模型-GAT在高性能预训练模型 GAT 交付中,快速理解业务背景,提前完成了ModelArts训练、SDK&MxBase推理,高质量达成交付要求。索尼(SONY)PS5 playstation dualscene 无线游戏手柄常顺西安电子科技大学苗启广MindX 高性能预训练模型-STGCN在高性能预训练模型 STGCN 交付中,快速理解业务需求,在极短的时间内完成了ModelArts训练、SDK推理,高质量达成交付要求。HUAWEI WATCH FIT彭超杨兴宇重庆大学郭松涛MindSpore框架-TCN模型-训练&推理彭超,杨兴宇同学开发高质高效,团队合作融洽,独立完成了TCN模型的训练和推理,多次输出心得分享,且带动团队其他同学加速开发进展。HUAWEI WATCH FIT华为手环 4杨艳娟兰州大学袁磊MindSpore框架-MMOE模型-训练&推理杨艳娟同学谦虚,谨慎,从零开始不断深入学习MindSpore框架,并热心帮助MindSpore群中其他遇到问题的同学,将自己的经验整理成干货满满的技术帖,一次性完成所有里程碑交付,是一名优秀的贡献者。华为手环 B6华为手环 4王佳祺重庆大学钟将MindSpore框架-KTNet模型-训练&推理在开发过程中主动思考,遇到困难也不畏缩,以高质量的交付证明了优秀的个人能力,提前数月完成验收。【46mm表盘】HUAWEI WATCH GT 2华为手环 6龚益玲宁波大学王翀PyTorch框架-C3D模型-训练在C3D训练模型交付中,善于思考,响应及时,独立自主解决各种问题,解决了精度调优等一系列问题。提前交付并高质量完成任务,且一次性通过验收。【42mm表盘】HUAWEI WATCH GT 2陈松宁波大学王翀ONNX框架-C3D模型-推理在C3D模型推理交付过程中,积极主动,认真分析问题,解决了模型转换,数据预处理,离线推理,精度评测等一系列问题,提前交付,并一次性通过验收。Freelace 无线耳机刘敬威南京理工大学代龙泉PyTorch框架-OpenPose模型-训练敬威同学在H2一共承接了3个训练模型任务,均为困难模型,对待交付认证,任务完成好,代码质量高,效率非常高,非常出色。【42mm表盘】HUAWEI WATCH GT 2高迪南京理工大学代龙泉ONNX框架-OpenPose模型-推理高迪同学接手模型后快速分析解决,接手半月就完成了交付,非常高效,提前2个月完成了交付。FreeBuds 4i 无线耳机张明坤中山大学张冬雨PyTorch框架-GAN模型-训练&ONNX框架-GAN模型-推理明坤同学作为跨专业的学生,首次接触深度学习及相关内容,也是首次接触昇腾业务,但是该同学善于学习,敢动手最终提前高质量交付第一个GAN网络,训练推理均一人完成。【42mm表盘】HUAWEI WATCH GT 2华为手环 6蔡立言中山大学张冬雨PyTorch框架-StarGAN模型-训练&ONNX框架-StarGAN模型-推理蔡立言同学积极思考,遇到问题及时求助,不惧困难,在完成stargan模型众展现了其专业能力和责任心,最终提前高质量交付第一个GAN网络,训练推理均一人完成。【42mm表盘】HUAWEI WATCH GT 2华为手环 6李怡南京大学谢磊TensorFlow框架-3D-POSE-BASELINE 模型-训练李怡同学负责3D-POSE-BASELINE模型的训练交付,提前高质量交付完成。同学对模型交付项目理解较好,整个项目交付过程比较顺利。在遇到性能问题时,通过提示信息顺利独立解决问题。华为 FreeGo刘子玮南京大学谢磊TensorFlow框架-MEMNET 模型-训练刘子玮同学负责MEMNET模型的训练交付,提前高质量交付完成。在遇到问题时能够主动思考并寻找解决方案进行尝试验证。FreeBuds 4 无线耳机白雄飞上海交通大学李雪松TensorFlow框架-SQUEEZESEG 模型-训练白雄飞同学代码能力较强,同时负责两个模型的交付任务,其中一个还涉及自定义算子适配,高质量提前交付SQUEEZESEG模型。模型交付过程中遇到数据预处理逻辑整改,精度和性能调优等多个难题,都能够按照指导顺利操作完成,表现优秀。【46mm表盘】HUAWEI WATCH GT 2张成武汉理工大学万源TensorFlow框架-SUBPIXEL 模型-训练在SUBPIXEL交付过程中,工作热情高,专业技能优秀,遇到问题能与CANN技术人员积极沟通解决问题,高校完成模型的训练任务,通过验收。【46mm表盘】HUAWEI WATCH GT 2张莹西安交通大学李垚辰TensorFlow框架-PROTOTYPICAL-NETWORKS 模型-训练在PROTOTYPICAL-NETWORKS模型的交付中,遇到问题能够主动思考、积极解决,高效率、高质量地完成了模型的训练,且承担的模型精度和性能均达标。在交付过程中,与支持人员积极沟通、解决问题,且乐于帮助项目组其他同学,和同学们分享经验、共同前行。【46mm表盘】HUAWEI WATCH GT 2韩迎萍西安电子科技大学谷裕TensorFlow框架-HybridSN 模型-训练在HybridSN中模型交付中,项目需求理解全面,通过积极的互动交流提前交付,交付质量高,通过验收。【42mm表盘】HUAWEI WATCH GT 2桂宁馨武汉大学焦雨领MindSpore算子-Acos & AcosGrad适配桂宁馨完成算子Acos,AcosGrad的MindSpore适配交付,提前提交并一次性通过验收,代码及测试用例质量高。华为手环 6刘永龙武汉理工大学熊盛武MindSpore算子-BesselI1e适配魏志清同学在ACosGrad算子交付中,克服深度学习相关基础的困难,积极学习,主动思考,积极与同学们共同探讨难题,与同学们共同进步,最后高效率完成交付验收。华为手环 6魏志清武汉理工大学熊盛武MindSpore算子-ReciprocalGrad适配刘永龙同学开发高质高效,团队合作融洽,积极主动,遇到困难不退缩,高质完成交付的任务华为手环 6感谢各位开发者的贡献,向各位优秀开发者学习!我们追求高质量交付,“一次性把事情做好”!活动持续,请大家参与“昇腾众智金质量奖”评选,活动链接:高质量交付众智开发任务,参与“昇腾众智金质量奖”评选,赢华为智能手表等超值奖品!历史展播 昇腾众智金质量奖展播 2021年第一期:You Are No.1昇腾众智金质量奖展播 2021年第二期:We Are Best昇腾众智金质量奖展播 2021年第三期:We Keep Going
-
#### 问题现象 在程序运行过程中,出现如下类似错误。 1.‘failed call to cuInit: CUDA\_ERROR\_NO\_DEVICE: no CUDA-capable device is detected’ 2.‘No CUDA-capable device is detected although requirements are installed’ #### 原因分析 出现该问题的可能原因如下: - 用户/训练系统,将CUDA\_VISIBLE\_DEVICES传错了,检查一下CUDA\_VISIBLE\_DEVICES变量是否正常。 - 用户选择了1/2/4卡这些规格的作业,然后设置了CUDA\_VISIBLE\_DEVICES=‘1’这种类似固定的卡ID号,与实际选择的卡ID不匹配。 #### 处理方法 1. 尽量代码里不要去修改CUDA\_VISIBLE\_DEVICES变量,用系统默认里面自带的。 2. 如果必须指定卡ID,需要注意一下1/2/4规格下,指定的卡ID与实际分配的卡ID不匹配的情况。 3. 如果上述方法还出现了错误,可以去notebook里面调试打印CUDA\_VISIBLE\_DEVICES变量,或者用以下代码测试一下,查看结果是否返回的是True。 import torch torch.cuda.is\_available()
上滑加载中
推荐直播
-
空中宣讲会 2025年华为软件精英挑战赛
2025/03/10 周一 18:00-19:00
宸睿 华为云存储技术专家、ACM-ICPC WorldFinal经验 晖哥
2025华为软挑赛空中宣讲会重磅来袭!完整赛程首曝+命题天团硬核拆题+三轮幸运抽奖赢参赛助力礼包,与全国优秀高校开发者同台竞技,直通顶尖赛事起跑线!
回顾中 -
华为开发者空间玩转DeepSeek
2025/03/13 周四 19:00-20:30
马欣 华为开发者布道师
同学们,想知道如何利用华为开发者空间部署自己的DeepSeek模型吗?想了解如何用DeepSeek在云主机上探索好玩的应用吗?想探讨如何利用DeepSeek在自己的专有云主机上辅助编程吗?让我们来一场云和AI的盛宴。
即将直播 -
华为云Metastudio×DeepSeek与RAG检索优化分享
2025/03/14 周五 16:00-17:30
大海 华为云学堂技术讲师 Cocl 华为云学堂技术讲师
本次直播将带来DeepSeek数字人解决方案,以及如何使用Embedding与Rerank实现检索优化实践,为开发者与企业提供参考,助力场景落地。
去报名
热门标签