那曲檬骨新材料有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

基于TPU-MLIR:詳解EinSum的完整處理過(guò)程!

算能開(kāi)發(fā)者社區(qū) ? 2024-02-19 13:08 ? 次閱讀

EinSum介紹

EinSum(愛(ài)因斯坦求和)是一個(gè)功能強(qiáng)大的算子,能夠簡(jiǎn)潔高效地表示出多維算子的乘累加過(guò)程,對(duì)使用者非常友好。

本質(zhì)上, EinSum是一個(gè)算子族,可以表示多種基礎(chǔ)操作,如矩陣乘法、Reduce。EinSum支持任意多的輸入,只要計(jì)算中只包含點(diǎn)乘(element-wise)、廣播(broadcast)、歸約求和(reduction sum)都可以使用EinSum來(lái)表示。以下給出一種將EinSum計(jì)算等價(jià)表達(dá)的流程:

  1. 將輸入的維度符號(hào)放入一個(gè)列表,移除重復(fù)元素后按升序排列;
  2. 對(duì)各輸入維度執(zhí)行轉(zhuǎn)置操作,確保維度標(biāo)識(shí)符按照升序?qū)R,實(shí)現(xiàn)維度對(duì)齊;
  3. 在缺失的維度上填充1(擴(kuò)展維度),以便與第一步中定義的維度保持一致;
  4. 對(duì)所有輸入執(zhí)行廣播點(diǎn)乘;
  5. 對(duì)那些不在輸出標(biāo)識(shí)符中的維度執(zhí)行累加操作;
  6. 利用轉(zhuǎn)置操作調(diào)整維度順序,使其與輸出標(biāo)識(shí)符的順序一致。

下圖是以out = EinSum("ijk, lki-> li", in0, in1)為例,根據(jù)上述步驟進(jìn)行等價(jià)轉(zhuǎn)換。e5439836-cee4-11ee-9118-92fbcf53809c.png

TPU-MLIR轉(zhuǎn)換

雖然使用上述流程可以完成對(duì)EinSum的計(jì)算轉(zhuǎn)換,但如果嚴(yán)格按照該流程執(zhí)行,會(huì)帶來(lái)大量的Transpose和Reshape操作,這不僅會(huì)給TPU-MLIR的LayerGroup功能帶來(lái)挑戰(zhàn),同時(shí)也難以顯式地識(shí)別出如矩陣乘法這類操作,從而無(wú)法充分利用硬件加速單元。因此,TPU-MLIR并未直接采用上述流程進(jìn)行轉(zhuǎn)換。

接下來(lái),我們將詳細(xì)介紹EinSum的完整處理過(guò)程。

前端接口

以下示例代碼摘自O(shè)nnxConverter.py文件,并附帶了注釋。代碼整體結(jié)構(gòu)簡(jiǎn)潔明了,我們可以看到,轉(zhuǎn)換函數(shù)目前僅支持兩個(gè)輸入的常見(jiàn)情況。特別需要注意的是公式的歸一化過(guò)程。由于EinSum的表達(dá)式可以使用任意非重復(fù)字符來(lái)表示下標(biāo),這雖然提高了可讀性,但也導(dǎo)致同一操作有多種不同的表示方式。歸一化操作就是將表達(dá)式字符重新映射,以字符'a'作為起始。例如,比如ij,jk->ik和dk,kv->dv都會(huì)映射為ab,bc->ac

#https://pytorch.org/docs/1.13/generated/torch.einsum.html?highlight=einsum#torch.einsum
defconvert_einsum_op(self,onnx_node):
assert(onnx_node.op_type=="Einsum")
equation=onnx_node.attrs.get("equation").decode()

#公式歸一化
defnormalize_equation(equation_c):
equation=equation_c
new_equation=''
start='a'
translate_map={}
forsinequation:
ifs=='':
continue
elifnot((s>='a'ands<=?'z')or(s>='A'ands<=?'Z')):
translate_map[s]=s
elifsnotintranslate_map:
translate_map[s]=start
start=chr(ord(start)+1)
new_equation+=translate_map[s]
returnnew_equation
equation=normalize_equation(equation)
lhs=self.getOperand(onnx_node.inputs[0])#
#大多情況下rhs是Weight, self.getOp會(huì)先到Weight Map中查找;如果找不到,
#其會(huì)從Mutable Tensor中查找,然后返回對(duì)應(yīng)的Value。
rhs=self.getOp(onnx_node.inputs[1])
new_op=top.EinsumOp(self.unranked_type,
[lhs,rhs],
mode=StringAttr.get(equation),
#設(shè)置loc信息,方便找到原圖對(duì)應(yīng)算子
loc=self.get_loc("{}_{}".format(onnx_node.name,onnx_node.op_type)),
#將該算子插入到當(dāng)前的block中
ip=self.mlir.insert_point).output
#將輸出放到MutableTensor列表中,供后面算子使用
self.addOperand(onnx_node.name,new_op)

內(nèi)部轉(zhuǎn)換

TPU-MLIR目前支持了幾種常見(jiàn)的表達(dá)式,并根據(jù)不同的算子進(jìn)行了優(yōu)化轉(zhuǎn)換。所有的變換最終都利用了硬件的矩陣乘法加速單元,從而實(shí)現(xiàn)了對(duì)算子的有效加速。以下是部分代碼片段,該代碼來(lái)自tpu-mlir/lib/Dialect/Top/Canonicalize/Einsum.cpp,并在原有基礎(chǔ)上添加了注釋。

structConvertEinsum:publicOpRewritePattern{
usingOpRewritePattern::OpRewritePattern;

LogicalResultmatchAndRewrite(EinsumOpop,
PatternRewriter&rewriter)constoverride{
//目前只支持輸入個(gè)數(shù)為2或者輸入0為Weight的情況
if(op.getInputs().size()!=2||module::isWeight(op.getInputs()[0])){
llvm_unreachable("Notsupportnow.");
//returnfailure();
}
autonone=module::getNoneOp(op);
automode=op.getMode().str();
autolhs=op.getInputs()[0];
autorhs=op.getInputs()[1];
autolshape=module::getShape(lhs);
autorshape=module::getShape(rhs);
std::stringlname=module::getName(lhs).str();
std::stringrname=module::getName(rhs).str();
std::stringname=module::getName(op.getOutput()).str();

std::vectoroperands;
std::vectorattrs;
if(mode=="a,b->ab"){
//外積操作:可看作[a,1]x[1,b]的矩陣乘法操作
//lhs->ReshapeOp():shape=[a]toshape[a,1]
rewriter.setInsertionPointAfter(lhs.getDefiningOp());
//
autonewType=RankedTensorType::get({lshape[0],1},module::getElementType(lhs));
autoloc=NameLoc::get(rewriter.getStringAttr(lname+"_to2dim"));
autolrsOp=rewriter.create(loc,newType,ValueRange{lhs});
operands.push_back(lrsOp);

//rhs->ReshapeOp():shape=[b]toshape[1,b]
rewriter.setInsertionPointAfter(rhs.getDefiningOp());
newType=RankedTensorType::get({1,rshape[0]},module::getElementType(rhs));
loc=NameLoc::get(rewriter.getStringAttr(rname+"_to2dim"));
autorrsop=rewriter.create(loc,newType,ValueRange{rhs});
operands.push_back(rrsop);
operands.push_back(none);
//用MatMulOp實(shí)現(xiàn)[a,1]x[1,b]=[a,b],并替換原來(lái)的EinSum操作
rewriter.setInsertionPoint(op);
automatmulOp=rewriter.create(op.getLoc(),op.getType(),operands,attrs);
op.replaceAllUsesWith(matmulOp.getOperation());
rewriter.eraseOp(op);
}elseif(mode=="abcd,cde->abe"){
//可以轉(zhuǎn)換成矩陣乘法[a*b,c*d]x[c*d,e]->[a*b,e]->[a,b,e]
//lhs_reshape_rst=[lhs_shape[0]*lhs_shape[1],lhs_shape[2]*lhs_shape[3]]
rewriter.setInsertionPointAfter(lhs.getDefiningOp());
autonewType=RankedTensorType::get({lshape[0]*lshape[1],lshape[2]*lshape[3]},module::getElementType(lhs));
autoloc=NameLoc::get(rewriter.getStringAttr(lname+"_to2dim"));
autolrsOp=rewriter.create(loc,newType,ValueRange{lhs});
operands.push_back(lrsOp);
newType=RankedTensorType::get({rshape[0]*rshape[1],rshape[2]},module::getElementType(rhs));
if(module::isWeight(rhs)){
rhs.setType(newType);
operands.push_back(rhs);
}else{
rewriter.setInsertionPointAfter(rhs.getDefiningOp());
loc=NameLoc::get(rewriter.getStringAttr(rname+"_to2dim"));
autorrsop=rewriter.create(loc,newType,ValueRange{rhs});
operands.push_back(rrsop);
}
operands.push_back(none);
rewriter.setInsertionPoint(op);
newType=RankedTensorType::get({lshape[0]*lshape[1],rshape[2]},module::getElementType(op));
loc=NameLoc::get(rewriter.getStringAttr(name+"_matmul"));
automatmulOp=rewriter.create(loc,newType,operands,attrs);
autoorsOp=rewriter.create(op.getLoc(),op.getType(),ValueRange{matmulOp});
op.replaceAllUsesWith(orsOp.getOperation());
rewriter.eraseOp(op);
}elseif(mode=="abcd,bed->abce"){
rewriter.setInsertionPointAfter(rhs.getDefiningOp());
//轉(zhuǎn)換過(guò)程
//batchmatmuldoesnotsupportbroadcast
//temporarysolution
//[h,k,c]->[1,h,k,c]->[b,h,k,c]
operands.push_back(lhs);

RankedTensorTypenewType;
//右操作數(shù)處理
if(autowOp=dyn_cast(rhs.getDefiningOp())){
//對(duì)于Weight來(lái)說(shuō),可以將數(shù)據(jù)復(fù)制,解決不支持廣播問(wèn)題,[b,e,d]->[a,b,e,d]
autostorage_type=module::getStorageType(rhs);
assert(storage_type.isF32()&&"Todo,supoortmoreweighttype");
autodata=wOp.read_as_byte();
uint8_t*dptr;
newType=RankedTensorType::get({lshape[0],rshape[0],rshape[1],rshape[2]},module::getElementType(rhs));
std::vector<float_t>new_filter(newType.getNumElements(),0);
dptr=(uint8_t*)new_filter.data();
//實(shí)際的數(shù)據(jù)復(fù)制過(guò)程
for(int32_ti=0;i0];i++){
autooffset=i*data->size();
memcpy(dptr+offset,data->data(),data->size());
}
autonew_op=top::create(op,"folder",new_filter,newType);
wOp.replaceAllUsesWith(new_op.getDefiningOp());
operands.push_back(new_op);
rewriter.eraseOp(wOp);
}else{
//對(duì)于普通tensor,先reshape成[1,b,e,d]再用tile算子翻倍數(shù)據(jù)為[a,b,e,d]

//Reshape操作
autoloc=NameLoc::get(rewriter.getStringAttr(rname+"_reshape"));
newType=RankedTensorType::get({1,rshape[0],rshape[1],rshape[2]},module::getElementType(rhs));
autorrsop=rewriter.create(loc,newType,ValueRange{rhs});

//Tile操作,各維tile倍數(shù)[a,1,1,1]
newType=RankedTensorType::get({lshape[0],rshape[0],rshape[1],rshape[2]},module::getElementType(rhs));
loc=NameLoc::get(rewriter.getStringAttr(rname+"_tile"));
attrs.push_back(rewriter.getNamedAttr("tile",rewriter.getI64ArrayAttr({lshape[0],1,1,1})));
autotileOp=rewriter.create(loc,newType,ValueRange{rrsop},attrs);
attrs.clear();
operands.push_back(tileOp);
}
operands.push_back(none);
//這里使用了右操作數(shù)轉(zhuǎn)置的批量矩陣乘法算子,硬件可直接支持
//[a*b,c,d]*[a*b,e,d]^T->[a*b,c,e]
attrs.push_back(rewriter.getNamedAttr("right_transpose",rewriter.getBoolAttr(true)));
rewriter.setInsertionPoint(op);
automatmulOp=rewriter.create(op.getLoc(),op.getType(),operands,attrs);
op.replaceAllUsesWith(matmulOp.getOperation());
rewriter.eraseOp(op);
}elseif(mode=="abcd,ced->abce"){
//dumbimplementation
//轉(zhuǎn)置lhs[a,b,c,d]->[a,c,b,d]
//trans_shape=[lhs_shape[0],lhs_shape[2],lhs_shape[1],lhs_shape[3]]
rewriter.setInsertionPointAfter(lhs.getDefiningOp());
autoloc=NameLoc::get(rewriter.getStringAttr(lname+"_trans"));
autonewType=RankedTensorType::get({lshape[0],lshape[2],lshape[1],lshape[3]},module::getElementType(lhs));
attrs.push_back(rewriter.getNamedAttr("order",rewriter.getI64ArrayAttr({0,2,1,3})));
autotranOp=rewriter.create(loc,newType,ValueRange{lhs},attrs);
attrs.clear();
operands.push_back(tranOp);

//復(fù)制或Tilelhs:[c,e,d]->[a,c,e,d]
rewriter.setInsertionPointAfter(rhs.getDefiningOp());
if(autowOp=dyn_cast(rhs.getDefiningOp())){
//Weight翻倍數(shù)據(jù)
autostorage_type=module::getStorageType(rhs);
assert(storage_type.isF32()&&"Todo,supoortmoreweighttype");
autodata=wOp.read_as_byte();
uint8_t*dptr;
newType=RankedTensorType::get({lshape[0],rshape[0],rshape[1],rshape[2]},module::getElementType(rhs));
std::vector<float_t>new_filter(newType.getNumElements(),0);
dptr=(uint8_t*)new_filter.data();
for(int32_ti=0;i0];i++){
autooffset=i*data->size();
memcpy(dptr+offset,data->data(),data->size());
}
autonew_op=top::create(op,"folder",new_filter,newType);
wOp.replaceAllUsesWith(new_op.getDefiningOp());
operands.push_back(new_op);
rewriter.eraseOp(wOp);
}else{
//rehshape+tile:[c,e,d]-reshape->[1,c,e,d]-tile->[a,c,e,d]
loc=NameLoc::get(rewriter.getStringAttr(rname+"_reshape"));
newType=RankedTensorType::get({1,rshape[0],rshape[1],rshape[2]},module::getElementType(rhs));
autorrsop=rewriter.create(loc,newType,ValueRange{rhs});
loc=NameLoc::get(rewriter.getStringAttr(rname+"_tile"));
attrs.push_back(rewriter.getNamedAttr("tile",rewriter.getI64ArrayAttr({lshape[0],1,1,1})));
newType=RankedTensorType::get({lshape[0],rshape[0],rshape[1],rshape[2]},module::getElementType(rhs));
autotileOp=rewriter.create(loc,newType,ValueRange{rrsop},attrs);
attrs.clear();
operands.push_back(tileOp);
}
operands.push_back(none);
//右操作數(shù)帶轉(zhuǎn)置批量矩陣乘法:[a*c, b, d]*[a*c, e, d]^T ->[a*c, b, e]->[a, c, b, e]
newType=RankedTensorType::get({lshape[0],lshape[2],lshape[1],rshape[1]},module::getElementType(op));
attrs.push_back(rewriter.getNamedAttr("right_transpose",rewriter.getBoolAttr(true)));
rewriter.setInsertionPoint(op);
loc=NameLoc::get(rewriter.getStringAttr(name+"_matmul"));
automatmulOp=rewriter.create(loc,newType,operands,attrs);
attrs.clear();
//[b,w,h,k]->[b,h,w,k]
attrs.push_back(rewriter.getNamedAttr("order",rewriter.getI64ArrayAttr({0,2,1,3})));
autotranBackOp=rewriter.create(op.getLoc(),op.getType(),ValueRange{matmulOp},attrs);
op.replaceAllUsesWith(tranBackOp.getOperation());
rewriter.eraseOp(op);
}elseif(mode=="abcd,abed->abce"||mode=="abcd,abde->abce"){
//lhs(abcd)*rhs(abed)^T->abce
//lhs(abcd)*rhs(abde)->abce
autonewType=RankedTensorType::get({lshape[0],lshape[1],lshape[2],rshape[2]},module::getElementType(op));
if(mode=="abcd,abde->abce"){
newType=RankedTensorType::get({lshape[0],lshape[1],lshape[2],rshape[3]},module::getElementType(op));
}
rewriter.setInsertionPoint(op);
rewriter.setInsertionPointAfter(rhs.getDefiningOp());
operands.push_back(lhs);
operands.push_back(rhs);
operands.push_back(none);
if(mode=="abcd,abed->abce"){
//rhs(abed)^T
attrs.push_back(rewriter.getNamedAttr("right_transpose",rewriter.getBoolAttr(true)));
}

autoloc=NameLoc::get(rewriter.getStringAttr(name));
automatmulOp=rewriter.create(loc,newType,operands,attrs);
op.replaceAllUsesWith(matmulOp.getOperation());
attrs.clear();
rewriter.eraseOp(op);

} elseif(mode=="abcd,cde->abce"){

//lhs:
//abcd->acbd(pemute)
//rhs:
//cde->1cde(reshape)
//acde->acde(tile)
//matmul:
//lhs(acbd)*rhs(acde)=result(acbe)
//result:
//acbe->abce(pemute)
//success!

rewriter.setInsertionPointAfter(lhs.getDefiningOp());
autoloc=NameLoc::get(rewriter.getStringAttr(lname+"_trans"));
autonewType=RankedTensorType::get({lshape[0],lshape[2],lshape[1],lshape[3]},module::getElementType(lhs));
attrs.push_back(rewriter.getNamedAttr("order",rewriter.getI64ArrayAttr({0,2,1,3})));
autotranOp=rewriter.create(loc,newType,ValueRange{lhs},attrs);
attrs.clear();
operands.push_back(tranOp);
rewriter.setInsertionPointAfter(rhs.getDefiningOp());
if(autowOp=dyn_cast(rhs.getDefiningOp())){

autodata=wOp.read_as_byte();
uint8_t*dptr;
newType=RankedTensorType::get({lshape[0],rshape[0],rshape[1],rshape[2]},module::getElementType(rhs));
std::vector<float_t>new_filter(newType.getNumElements(),0);
dptr=(uint8_t*)new_filter.data();
for(int32_ti=0;i0];i++){
autooffset=i*data->size();
memcpy(dptr+offset,data->data(),data->size());
}
autonew_op=top::create(op,"folder",new_filter,newType);
wOp.replaceAllUsesWith(new_op.getDefiningOp());
operands.push_back(new_op);
rewriter.eraseOp(wOp);
}else{
loc=NameLoc::get(rewriter.getStringAttr(rname+"_reshape"));
newType=RankedTensorType::get({1,rshape[0],rshape[1],rshape[2]},module::getElementType(rhs));
autorrsop=rewriter.create(loc,newType,ValueRange{rhs});
loc=NameLoc::get(rewriter.getStringAttr(rname+"_tile"));
attrs.push_back(rewriter.getNamedAttr("tile",rewriter.getI64ArrayAttr({lshape[0],1,1,1})));
newType=RankedTensorType::get({lshape[0],rshape[0],rshape[1],rshape[2]},module::getElementType(rhs));
autotileOp=rewriter.create(loc,newType,ValueRange{rrsop},attrs);
attrs.clear();
operands.push_back(tileOp);
}
operands.push_back(none);
newType=RankedTensorType::get({lshape[0],lshape[2],lshape[1],rshape[2]},module::getElementType(op));
rewriter.setInsertionPoint(op);
loc=NameLoc::get(rewriter.getStringAttr(name+"_matmul"));
automatmulOp=rewriter.create(loc,newType,operands,attrs);
attrs.clear();
attrs.push_back(rewriter.getNamedAttr("order",rewriter.getI64ArrayAttr({0,2,1,3})));
autotranBackOp=rewriter.create(op.getLoc(),op.getType(),ValueRange{matmulOp},attrs);
op.replaceAllUsesWith(tranBackOp.getOperation());
rewriter.eraseOp(op);

}else{
llvm_unreachable("Einsumnotsupportthismodenow");
}
returnsuccess();
}

總結(jié)

TPU-MLIR對(duì)EinSum的實(shí)現(xiàn)雖然不完全,但已經(jīng)足夠?qū)嵱茫軡M足目前常見(jiàn)網(wǎng)絡(luò)的需求。通過(guò)Converter直接表達(dá)式規(guī)范化,降低了編譯器優(yōu)化或模式分析的復(fù)雜性。在算子分析時(shí),我們不僅需要在計(jì)算上實(shí)現(xiàn)等價(jià)變換,還需充分了解實(shí)際硬件的特性。針對(duì)不同硬件架構(gòu)及其對(duì)算子的支持情況,需具體分析以找到最佳實(shí)現(xiàn)方法。此外,我們可以看到在工程實(shí)踐中,人們更注重實(shí)用性和效率,在實(shí)現(xiàn)上不必追求完備,是要覆蓋實(shí)際應(yīng)用場(chǎng)景即可。EinSum的轉(zhuǎn)換還有改進(jìn)空間,我們也歡迎社區(qū)提出寶貴的建議并貢獻(xiàn)代碼。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 前端
    +關(guān)注

    關(guān)注

    1

    文章

    200

    瀏覽量

    17840
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4825

    瀏覽量

    69046
  • TPU
    TPU
    +關(guān)注

    關(guān)注

    0

    文章

    143

    瀏覽量

    20783
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    使用ADS1274 ADC進(jìn)行前端信號(hào)采集,前端信號(hào)調(diào)理過(guò)程中是否還需要設(shè)計(jì)AA Filter?

    本人打算使用ADS1274 ADC進(jìn)行前端信號(hào)采集,信號(hào)帶寬大概為1Khz 至 11Khz,使用ADC的快速采樣模式,外部振蕩器頻率為32.768MHz。 現(xiàn)在遇到的問(wèn)題是,不知道前端信號(hào)調(diào)理過(guò)程
    發(fā)表于 01-22 08:18

    光纜用tpu外護(hù)套用在哪些型號(hào)光纜上

    光纜用TPU(熱塑性聚氨酯)外護(hù)套因其耐磨、抗拉、柔性好以及優(yōu)良的防潮和阻燃性能,被廣泛應(yīng)用于多種型號(hào)的光纜上,特別是需要較高機(jī)械保護(hù)和惡劣環(huán)境適應(yīng)性的光纜。以下是一些可能使用TPU外護(hù)套的光纜
    的頭像 發(fā)表于 01-10 10:05 ?133次閱讀

    ADS1284 MFLG應(yīng)該怎么處理

    如果模擬端出現(xiàn)一個(gè)超量程的信號(hào),MFLAG就會(huì)激活,如果這時(shí)不Reset ADC,是不是后續(xù)ADC的輸出都會(huì)是0?如果Reset然后重新SYNC,在處理過(guò)程中是否就會(huì)丟掉一些數(shù)據(jù)?MFLAG應(yīng)該怎么處理
    發(fā)表于 11-29 06:54

    處理器指令的獲取過(guò)程

    處理器指令的獲取是計(jì)算機(jī)執(zhí)行程序過(guò)程中的關(guān)鍵環(huán)節(jié),它決定了微處理器如何對(duì)數(shù)據(jù)和指令進(jìn)行處理。以下將詳細(xì)闡述微處理器指令的獲取
    的頭像 發(fā)表于 10-05 15:16 ?425次閱讀

    PLC水處理過(guò)濾器運(yùn)維管理系統(tǒng)解決方案

    ,數(shù)之能提供PLC云組態(tài)平臺(tái)的PLC水處理過(guò)濾器運(yùn)維管理系統(tǒng)解決方案。通過(guò)接入PLC設(shè)備數(shù)據(jù),PLC云組態(tài)平臺(tái)可以形成水處理過(guò)濾系統(tǒng)的組態(tài)界面,實(shí)時(shí)展示設(shè)備狀態(tài)、工藝參數(shù)等信息;管理人員也能遠(yuǎn)程查看告警信息并進(jìn)行運(yùn)維操作,及時(shí)
    的頭像 發(fā)表于 09-23 10:44 ?293次閱讀

    TPU v1到Trillium TPU,蘋果等科技公司使用谷歌TPU進(jìn)行AI計(jì)算

    ,在訓(xùn)練尖端人工智能方面,大型科技公司正在尋找英偉達(dá)以外的替代品。 ? 不斷迭代的谷歌TPU 芯片 ? 隨著機(jī)器學(xué)習(xí)算法,特別是深度學(xué)習(xí)算法在各個(gè)領(lǐng)域的廣泛應(yīng)用,對(duì)于高效、低功耗的AI計(jì)算硬件需求日益增長(zhǎng)。傳統(tǒng)的CPU和GPU在處理這些算法時(shí)存在效率較低的問(wèn)
    的頭像 發(fā)表于 07-31 01:08 ?3439次閱讀

    PLC對(duì)模擬量信號(hào)的處理過(guò)程及方法 詳解

    )。 PLC通過(guò)計(jì)算轉(zhuǎn)換,將這些模擬量信號(hào)轉(zhuǎn)換為內(nèi)部的數(shù)值信號(hào)。從而實(shí)現(xiàn)系統(tǒng)的監(jiān)控及控制。從現(xiàn)場(chǎng)的物理信號(hào)到PLC內(nèi)部處理的數(shù)值信號(hào),有以下幾個(gè)步驟: 從以上PLC模擬量的信號(hào)輸入流程可以看到,在自動(dòng)化過(guò)程控制系統(tǒng)中,模擬量信號(hào)的輸入是非
    的頭像 發(fā)表于 07-30 16:31 ?485次閱讀
    PLC對(duì)模擬量信號(hào)的<b class='flag-5'>處理過(guò)程</b>及方法 <b class='flag-5'>詳解</b>版

    【算能RADXA微服務(wù)器試用體驗(yàn)】+ GPT語(yǔ)音與視覺(jué)交互:2,圖像識(shí)別

    /download.sh 下載完成后,應(yīng)該可以看到文件夾中出現(xiàn)以下模型: ./models ├── BM1684 │├── yolov8s_fp32_1b.bmodel# 使用TPU-MLIR編譯,用于
    發(fā)表于 07-14 23:36

    自然語(yǔ)言處理過(guò)程的五個(gè)層次

    自然語(yǔ)言處理(NLP)的五個(gè)層次: 詞法分析(Lexical Analysis): 詞法分析是NLP的第一步,它涉及將文本分解為基本單位,通常是單詞或標(biāo)記。 詞法分析的目的是識(shí)別文本中的詞匯
    的頭像 發(fā)表于 07-03 14:27 ?825次閱讀

    什么是信號(hào)完整

    在現(xiàn)代電子通信和數(shù)據(jù)處理系統(tǒng)中,信號(hào)完整性(Signal Integrity, SI)是一個(gè)至關(guān)重要的概念。它涉及信號(hào)在傳輸過(guò)程中的質(zhì)量保持,對(duì)于確保系統(tǒng)性能和穩(wěn)定性具有決定性的影響。本文將從信號(hào)
    的頭像 發(fā)表于 05-28 14:30 ?1309次閱讀

    谷歌將推出第六代數(shù)據(jù)中心AI芯片Trillium TPU

    在今日舉行的I/O 2024開(kāi)發(fā)者大會(huì)上,谷歌公司震撼發(fā)布了其第六代數(shù)據(jù)中心AI芯片——Trillium Tensor處理器單元(TPU)。據(jù)谷歌首席執(zhí)行官皮查伊透露,這款新型TPU預(yù)計(jì)在年內(nèi)交付,屆時(shí)將帶來(lái)前所未有的計(jì)算性能飛
    的頭像 發(fā)表于 05-15 11:18 ?673次閱讀

    maixcam部署yolov5s 自定義模型

    ://github.com/sophgo/tpu-mlir/releases/tag/v1.7 上面網(wǎng)址下載 tpu-mlir-resource.tar 和 tpu_mlir
    發(fā)表于 04-23 15:43

    大語(yǔ)言模型(LLMs)如何處理多語(yǔ)言輸入問(wèn)題

    研究者們提出了一個(gè)框架來(lái)描述LLMs在處理多語(yǔ)言輸入時(shí)的內(nèi)部處理過(guò)程,并探討了模型中是否存在特定于語(yǔ)言的神經(jīng)元。
    發(fā)表于 03-07 14:44 ?698次閱讀
    大語(yǔ)言模型(LLMs)如何<b class='flag-5'>處理</b>多語(yǔ)言輸入問(wèn)題

    圖像編碼常見(jiàn)的編碼方式和處理過(guò)程

    圖像編碼是將圖像數(shù)據(jù)轉(zhuǎn)換為數(shù)字形式的過(guò)程,通常通過(guò)壓縮圖像數(shù)據(jù)以便于存儲(chǔ)和傳輸。圖像編碼的主要目標(biāo)是在盡可能減少數(shù)據(jù)量的同時(shí),保持圖像質(zhì)量,以實(shí)現(xiàn)高效的存儲(chǔ)和傳輸。
    的頭像 發(fā)表于 02-26 14:32 ?1.2w次閱讀

    關(guān)于數(shù)字圖像處理的常用技巧

    圖像生成采集處理過(guò)程中都會(huì)不同程度的引入各種噪聲,因此會(huì)導(dǎo)致圖像的質(zhì)量變差。從而影響對(duì)圖像的識(shí)別。所以必須要對(duì)圖像進(jìn)行濾波,所以必須對(duì)圖像進(jìn)行濾波。
    的頭像 發(fā)表于 02-19 09:27 ?1005次閱讀
    關(guān)于數(shù)字圖像<b class='flag-5'>處理</b>的常用技巧
    金花娱乐城注册| 六合彩报码聊天室| 百家乐娱乐平台网77scs| 利高百家乐游戏| 百家乐官网路单走势图| 百家乐官网游戏公司| 六合彩130| 大发888提款怎么提| 百家乐人生信条漫谈| 银河百家乐官网的玩法技巧和规则 | 马尔康县| 顶尖娱乐城开户| 大发888真钱娱乐游戏| 重庆百家乐的玩法技巧和规则| 15人百家乐桌布| 24山64卦分金| 百家乐官网乐翻天| 百家乐官网赌博经历| 在线百家乐官网官方网| 平阴县| 威尼斯人娱乐城首选802com| 送彩金百家乐的玩法技巧和规则| 百家乐精神| 网上百家乐怎么破解| 乐九百家乐游戏| 博彩百家乐官网组选六六组 | 百家乐官网庄闲| 百家乐官网代打公司| 麦盖提县| zaixian百家乐| 澳门博彩网| 立博| 真龙娱乐| 尊爵| 皇冠百家乐| 云鼎娱乐场| 优博平台| 赌场风云国语| 拉斯维加斯| 壹贰博娱乐城| 互助|