Triton IR

Triton IR語法

Triton IR的語句遵從MLIR Dialect的語法定義規范,示例如下:

%3 = tt.splat %1 : i32 -> tensor<1024xi32> loc(#loc5)

其中:

%0:右邊expression的結果值的名字(Value的name)

tt:表示Dialect名稱空間為tt(Triton)

splat:operation的名字

%1:operation的輸入

i32:%1的類型

tensor<1024*i32>:operation的結果類型(即3%的類型)

loc(%loc5):對應源碼的行號,調試信息。

?如下是一個pytorch cat算子的Triton DSL(inductor產生)

@triton.jit
def triton_(in_ptr0, in_ptr1, out_ptr0, xnumel, XBLOCK : tl.constexpr):xnumel = 3645440xoffset = tl.program_id(0) * XBLOCKxindex = xoffset + tl.arange(0, XBLOCK)[:]xmask = tl.full([XBLOCK], True, tl.int1)x0 = xindex % 890x1 = (xindex // 890)x2 = xindextmp0 = x0tmp1 = tl.full([1], 0, tl.int64)tmp2 = tmp0 >= tmp1tmp3 = tl.full([1], 390, tl.int64)tmp4 = tmp0 < tmp3tmp5 = tl.load(in_ptr0 + ((390*x1) + x0), tmp4, eviction_policy='evict_last', other=0.0)tmp6 = tmp0 >= tmp3tmp7 = tl.full([1], 890, tl.int64)tmp8 = tmp0 < tmp7tmp9 = tl.load(in_ptr1 + ((500*x1) + ((-390) + x0)), tmp6, eviction_policy='evict_last', other=0.0)tmp10 = tl.where(tmp4, tmp5, tmp9)tl.store(out_ptr0 + (x2), tmp10, None)
''', device_str='cuda')

編譯生成的Triton IR如下::

#loc = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":18:0)
module {tt.func public @triton_(%arg0: !tt.ptr<f32> {tt.divisibility = 16 : i32} loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":18:0), %arg1: !tt.ptr<f32> {tt.divisibility = 16 : i32} loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":18:0), %arg2: !tt.ptr<f32> {tt.divisibility = 16 : i32} loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":18:0), %arg3: i32 {tt.divisibility = 16 : i32} loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":18:0)) attributes {noinline = false} {%cst = arith.constant dense<-390> : tensor<1024xi32> loc(#loc1)%cst_0 = arith.constant dense<500> : tensor<1024xi32> loc(#loc1)%cst_1 = arith.constant dense<0.000000e+00> : tensor<1024xf32> loc(#loc1)%cst_2 = arith.constant dense<390> : tensor<1024xi32> loc(#loc1)%cst_3 = arith.constant dense<390> : tensor<1024xi64> loc(#loc1)%cst_4 = arith.constant dense<890> : tensor<1024xi32> loc(#loc1)%c1024_i32 = arith.constant 1024 : i32 loc(#loc1)%0 = tt.get_program_id x : i32 loc(#loc2)%1 = arith.muli %0, %c1024_i32 : i32 loc(#loc3)%2 = tt.make_range {end = 1024 : i32, start = 0 : i32} : tensor<1024xi32> loc(#loc4)%3 = tt.splat %1 : i32 -> tensor<1024xi32> loc(#loc5)%4 = arith.addi %3, %2 : tensor<1024xi32> loc(#loc5)%5 = arith.remsi %4, %cst_4 : tensor<1024xi32> loc(#loc6)%6 = arith.divsi %4, %cst_4 : tensor<1024xi32> loc(#loc7)%7 = arith.extsi %5 : tensor<1024xi32> to tensor<1024xi64> loc(#loc8)%8 = arith.cmpi slt, %7, %cst_3 : tensor<1024xi64> loc(#loc8)%9 = arith.muli %6, %cst_2 : tensor<1024xi32> loc(#loc9)%10 = arith.addi %9, %5 : tensor<1024xi32> loc(#loc10)%11 = tt.splat %arg0 : !tt.ptr<f32> -> tensor<1024x!tt.ptr<f32>> loc(#loc11)%12 = tt.addptr %11, %10 : tensor<1024x!tt.ptr<f32>>, tensor<1024xi32> loc(#loc11)%13 = tt.load %12, %8, %cst_1 evictionPolicy = evict_last : tensor<1024x!tt.ptr<f32>> loc(#loc12)%14 = arith.cmpi sge, %7, %cst_3 : tensor<1024xi64> loc(#loc13)%15 = arith.muli %6, %cst_0 : tensor<1024xi32> loc(#loc14)%16 = arith.addi %5, %cst : tensor<1024xi32> loc(#loc15)%17 = arith.addi %15, %16 : tensor<1024xi32> loc(#loc16)%18 = tt.splat %arg1 : !tt.ptr<f32> -> tensor<1024x!tt.ptr<f32>> loc(#loc17)%19 = tt.addptr %18, %17 : tensor<1024x!tt.ptr<f32>>, tensor<1024xi32> loc(#loc17)%20 = tt.load %19, %14, %cst_1 evictionPolicy = evict_last : tensor<1024x!tt.ptr<f32>> loc(#loc18)%21 = arith.select %8, %13, %20 : tensor<1024xi1>, tensor<1024xf32> loc(#loc19)%22 = tt.splat %arg2 : !tt.ptr<f32> -> tensor<1024x!tt.ptr<f32>> loc(#loc20)%23 = tt.addptr %22, %4 : tensor<1024x!tt.ptr<f32>>, tensor<1024xi32> loc(#loc20)tt.store %23, %21 : tensor<1024x!tt.ptr<f32>> loc(#loc21)tt.return loc(#loc22)} loc(#loc)
} loc(#loc)
#loc1 = loc(unknown)
#loc2 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":20:28)
#loc3 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":20:33)
#loc4 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":21:36)
#loc5 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":21:23)
#loc6 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":23:18)
#loc7 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":24:20)
#loc8 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":30:18)
#loc9 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":31:35)
#loc10 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":31:41)
#loc11 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":31:30)
#loc12 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":31:46)
#loc13 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":32:19)
#loc14 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":35:35)
#loc15 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":35:51)
#loc16 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":35:42)
#loc17 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":35:30)
#loc18 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":35:57)
#loc19 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":36:33)
#loc20 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":37:25)
#loc21 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":37:37)
#loc22 = loc("/tmp/torchinductor_vincent/yx/cyxlesomwjvogzqnvxmuj2p2z2gml7hud473ghmveu4fg6jbtlmz.py":37:4)

Triton IR依賴的Dialects

編寫完triton程序后,導出的IR中,可以看到不止有triton IR,還包含其他的MLIR Dialects,其中包含:

  • Arith: addf, addi, andi, cmpf, cmpi, divf, fptosi, …

  • Math: exp, sin, cos, log, …

  • StructuredControlFlow(scf): for, if, while, yield, condition

  • ControlFlow(cf): br, cond_br

Triton IR Operations

tt.call?(triton::CallOp)

語法:

operation ::= `tt.call` $callee `(` $operands `)` attr-dict `:` functional-type($operands, results)

tt.call表示對同一個符號作用域內的函數的直接調用。

示例:

%2 = tt.call @my_add(%0, %1) : (f32, f32) -> f32

tt.func?(triton::FuncOp)

function聲明或定義,function是一個SSACFG region。

function內的Operation不能隱式地捕獲function外定義的值。所有外部引用都必須通過arguments或者attribute來傳遞。在MLIR中,function的arguments是通過第一個block的block arguments來表達的。

示例:

// External function definitions.
tt.func @abort()
tt.func @scribble(i32, i64, memref<? x 128 x f32, #layout_map0>) -> f64// A function that returns its argument twice:
tt.func @count(%x: i64) -> (i64, i64)attributes {fruit: "banana"} {return %x, %x: i64, i64
}// A function with an argument attribute
tt.func @example_fn_arg(%x: i32 {swift.self = unit})// A function with a result attribute
tt.func @example_fn_result() -> (f64 {dialectName.attrName = 0 : i64})// A function with an attribute
tt.func @example_fn_attr() attributes {dialectName.attrName = false}

SSACFG region

SSACFG region內的語句滿足SSA形式,且不包含子Region(既不能包含scf.if/scf.for等),如下就是一個SSACFG region:

func.func @example(%a : i32) -> i32 {// 這是一個 SSACFG Region%cmp = arith.cmpi slt, %a, %c10 : i32cond_br %cmp, ^bb1, ^bb2^bb1:%x = arith.addi %a, %c1 : i32br ^exit(%x : i32)^bb2:%y = arith.subi %a, %c1 : i32br ^exit(%y : i32)^exit(%result : i32):return %result : i32
}

如下不是一個SSACFG Region:

scf.if %cond {// 這里是一個新的 Region(嵌套)scf.yield
}

Block Arguments

對如下函數:

func.func @foo(%arg0: i32, %arg1: f32) -> f32 {// 函數體直接使用 %arg0, %arg1%result = arith.addf %arg1, %arg1 : f32return %result : f32
}

在MLIR的內部實現里,是把function的arguments作為function內第一個基本塊(entry block)的 block arguments 來存儲:

func.func @foo() -> f32 {
^bb0(%arg0: i32, %arg1: f32):   // ← 參數實際屬于 entry block%result = arith.addf %arg1, %arg1 : f32return %result : f32
}

這是因為MLIR的設計要求所有 SSA 值都由某個 block 或 op 產生,這樣做也解決了LLVM IR中的phi node的問題。

在LLVM IR中,通過phi node來匯聚不同前驅路徑的值,示例如下:

entry:br i1 %cond, label %left, label %rightleft:br label %mergeright:br label %mergemerge:%x = phi i32 [ %v1, %left ], [ %v2, %right ]   ; ← φ 節點ret i32 %x

在MLIR中,通過block arguments,可以實現同等的效果:

func.func @foo(%cond: i1, %v1: i32, %v2: i32) -> i32 {cf.cond_br %cond, ^left, ^right^left:cf.br ^merge(%v1 : i32)     // 把 %v1 作為參數傳給 merge^right:cf.br ^merge(%v2 : i32)     // 把 %v2 作為參數傳給 merge^merge(%x : i32):             // ← block argument 取代 φreturn %x : i32

tt.return?(triton::ReturnOp)

語法:

operation ::= `tt.return` attr-dict ($srcs^ `:` type($srcs))?

表達function的返回操作,擁有變長個數的操作數,操作數的個數和類型必須和function的簽名匹配。

示例:

tt.func @foo() : (i32, f8) {...tt.return %0, %1 : i32, f8
}

tt.addptr?(triton::AddPtrOp)

語法:

operation ::= `tt.addptr` $ptr `,` $offset attr-dict `:` type($result) `,` type($offset)

張量或標量指針地址線性偏移計算。

示例:

%base = tt.splat %arg0 : !tt.ptr<f32> -> tensor<1024x!tt.ptr<f32>>
%idx  = tt.make_range {start = 0, end = 1024} : tensor<1024xi32>// 生成偏移地址
%ptrs = tt.addptr %base, %idx: tensor<1024x!tt.ptr<f32>>, tensor<1024xi32>// 加載數據
%vals = tt.load %ptrs : tensor<1024xf32>

tt.advance?(triton::AdvanceOp)

語法:

operation ::= `tt.advance` $ptr `,` `[` $offsets `]` attr-dict `:` type($result)

!tt.ptr<tensor<...>> 類型的指針按給定的 多維偏移量 進行偏移計算,返回一個新的張量指針。

示例:

scf.for %i = %c0 to %c128 step %c32iter_args(%tile_ptr = %base_ptr) -> (!tt.ptr<tensor<32x32xf16>>) {// 使用當前 tile%vals = tt.load %tile_ptr : !tt.ptr<tensor<32x32xf16>>// 推進到下一個 tile(第1個維度上推進 32,第2個維度保持不變)%next_ptr = tt.advance %tile_ptr, [%c32_i32, %c0_i32] : !tt.ptr<tensor<32x32xf16>>scf.yield %next_ptr : !tt.ptr<tensor<32x32xf16>>
}

tt.assert?(triton::AssertOp)

語法:

operation ::= `tt.assert` $condition `,` $message attr-dict `:` type($condition)

tt.assert作用在device側,接收1個condition(i1 類型的標量或張量)和一個string. 如果condition為false,則打印message并終止程序。

示例:

%in_bounds = arith.cmpi slt, %idx, %size : i32
tt.assert %in_bounds, "index out of bounds"

TODO

參考資料:

TritonOps — Triton documentation

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/90748.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/90748.shtml
英文地址,請注明出處:http://en.pswp.cn/web/90748.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

掌握JavaScript函數封裝與作用域

JavaScript 基礎 - 第4天筆記理解封裝的意義&#xff0c;能夠通過函數的聲明實現邏輯的封裝&#xff0c;知道對象數據類型的特征&#xff0c;結合數學對象實現簡單計算功能。理解函數的封裝的特征掌握函數聲明的語法理解什么是函數的返回值知道并能使用常見的內置函數函數理解函…

Datawhale AI 夏令營—科大訊飛AI大賽(大模型技術)—讓大模型理解表格數據(列車信息表)

目錄 一、本次賽事目標&#xff1a;讓大模型理解表格數據&#xff08;列車信息表&#xff09; 二、分析賽題、對問題進行建模 賽事背景 賽題解讀 數據分析與探索 賽題要點與難點 解題思考過程 三、Baseline方案 Baseline概況 Baseline運行步驟 Baseline文件概況 Ba…

SSH連接失敗排查與解決教程: Connection refused

前言 當使用云服務器&#xff08;如阿里云、騰訊云、AWS 等&#xff09;時&#xff0c;嘗試在本地PC端使用圖形化工具如 FinalShell、XShell可能會遇到 SSH 連接失敗的問題。本文列舉 SSH 連接失敗的常見原因&#xff0c;并提供對應解決方案&#xff0c;幫助快速定位并解決問題…

性能優化:Vue 3 `v-memo` 指令詳解

v-memo 是 Vue 3 提供的一個性能優化工具&#xff0c;能幫助開發者緩存模板內容&#xff0c;減少不必要的渲染開銷。本文將介紹 v-memo 的引入版本、作用、使用方法和實現原理&#xff0c;并通過示例說明如何使用它。內容基于 Vue 3.5.18&#xff08;截至 2025 年 7 月的最新版…

標準庫開發和寄存器開發的區別

1.標準庫void GPIO_Toggle_INIT(void)//初始化GPIO {GPIO_InitTypeDef GPIO_InitStructure {0};//定義GPIO結構體RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);//使能GPIO時鐘GPIO_InitStructure.GPIO_Pin GPIO_Pin_2;//GPIO引腳選擇GPIO_InitStructure.GPIO_Mode …

在 WebSocket 中使用 @Autowired 時遇到空指針異常

背景&#xff1a;在websocket在有新的連接加入進來時&#xff0c;調用servier中的服務&#xff0c;使用 Autowired 注入的 Bean 竟然是 null&#xff01;這并非 Spring 的 Bug&#xff0c;而是對 WebSocket 生命周期管理理解不足導致的。了解這個問題&#xff0c;我們需要區分兩…

MGER實驗

一、實驗拓撲圖二、配置1.R5為ISP&#xff0c;只能進行IP地址配置&#xff0c;其所有地址均配為公有IP地址R1側為15.1.1.1&#xff0c;對應R5為15.1.1.2R2側為25.1.1.2&#xff0c;對應R5為25.1.1.1R3側為35.1.1.2&#xff0c;對應R5為35.1.1.1R4側為45.1.1.2&#xff0c;對應R…

基于 XGBoost 與 SHAP 的醫療自動化辦公與可視化系統(下)

— 登錄接口 — @app.post(“/token”) def login(form_data: OAuth2PasswordRequestForm = Depends()): user = fake_users_db.get(form_data.username) if not user or form_data.password != user[“password”]: raise HTTPException(status_code=400, detail=“用戶名或密…

python學智能算法(二十九)|SVM-拉格朗日函數求解中-KKT條件

引言 前序學習進程中&#xff0c;對拉格朗日函數執行了初步求導&#xff0c;并獲得了簡化后的拉格朗日函數極值計算式&#xff1a; L(w,b,α)∑i1mαi?12∑i,j1mαiαjyiyjxiTxjL(w,b,\alpha)\sum_{i1}^{m}\alpha_{i}-\frac{1}{2}\sum_{i,j1}^{m}\alpha_{i}\alpha_{j}y_{i}y_…

【AI論文】MiroMind-M1:通過情境感知多階段策略優化實現數學推理的開源新進展

摘要&#xff1a;近期&#xff0c;大型語言模型已從流暢的文本生成發展至能在多個領域進行高級推理&#xff0c;由此催生了推理語言模型&#xff08;RLMs&#xff09;。在眾多領域中&#xff0c;數學推理堪稱代表性基準&#xff0c;因為它需要精確的多步驟邏輯與抽象推理能力&a…

《使用Qt Quick從零構建AI螺絲瑕疵檢測系統》——6. 傳統算法實戰:用OpenCV測量螺絲尺寸

目錄一、概述1.1 背景介紹&#xff1a;從“看見”到“看懂”1.2 學習目標二、圖像預處理&#xff1a;讓目標更突出三、輪廓發現與尺寸測量四、總結與展望一、概述 1.1 背景介紹&#xff1a;從“看見”到“看懂” 在上一篇文章中&#xff0c;我們成功地為應用程序安裝了“眼睛…

《人性的弱點》重構【01】

手上有本《人性的弱點》&#xff08;韓文橋 譯&#xff0c;浙江文藝出版社&#xff0c;2017.1出版&#xff09;&#xff0c;前些年買的&#xff0c;近期翻出來看看。這門書雖成書于80多年前&#xff0c;但卡耐基對人性洞察之深刻&#xff0c;時至今日&#xff0c;并未覺得過時。…

k8s開啟審計日志

k8s默認是關閉審計功能的&#xff0c;想看的話需要到apiserver的pod中才可以。 開啟此功能是為了進行k8s審計日志的收集&#xff0c;方便我們查看k8s中用戶的各自操作。 開啟此功能之前&#xff0c;我們要先創建個審計策略文件audit-policy.yaml 例如以下的測驗文件 apiVersion…

Kafka MQ 消費者應用場景

Kafka MQ 消費者應用場景 1 消費者自動提交的時機 在 Kafka 中默認的消費位移的提交方式是自動提交,這個由消費者客戶端參數 enable.auto.commit 配置,默認值為 true。當然這個默認的自動提交不是每消費一條消息就提交一次,而是定期提交,這個定期的周期時間由客戶端參數 …

Git版本控制系統

Git作為目前最流行的分布式版本控制系統&#xff0c;已經成為開發者必備的技能之一。本文將全面介紹Git的核心概念、基本操作、分支管理以及與GitHub的協作開發&#xff0c;幫助讀者從零開始掌握Git的使用。 一、Git概述 1.1 Git發展歷史 Git誕生于2005年&#xff0c;由Linu…

如何編譯RustDesk(Unbuntu 和Android版本)

編譯Linux版本的RustDesk備注&#xff1a;官方文檔上&#xff0c;一邊都是基于sciter&#xff0c;這個在后面已經不建議使用了&#xff0c;但是依然可以編譯剛開始的時候看官方的文檔&#xff0c;涉及的東西比較多&#xff0c;也搞的一頭霧水&#xff0c;通過B站上一個視頻&…

Spring中的循環依賴:解密、破局與架構啟示

> 當兩個Bean緊緊相擁,Spring容器卻陷入死鎖——這是Java開發者的經典噩夢 某電商平臺凌晨上線時突然宕機,日志里反復滾動著`BeanCurrentlyInCreationException`的報錯。經排查,**優惠券服務與庫存服務在初始化時相互依賴**,形成致命閉環。這個價值百萬的故障案例,揭開…

DataFrame?(數據框)

一種二維表格型數據結構&#xff0c;類似于電子表格&#xff08;如 Excel&#xff09;或 SQL 表&#xff0c;由行&#xff08;記錄&#xff09;?和列&#xff08;字段&#xff09;?組成。它是數據分析、機器學習和科學計算中最常用的數據結構之一&#xff0c;尤其在 ?Python…

B站視頻評論數據爬取

爬取B站視頻評論數據爬取與分析 如果只要單純的腳本可以直接看項目結構里的b_comments.py 一、技術架構 1、環境配置 Python 3.8PyCharm 2、模塊配置 requests&#xff1a;用于發送HTTP請求time&#xff1a;用于處理時間相關的操作csv&#xff1a;用于讀寫CSV文件json&#xff…

OpenAI最新大模型GPT-4o體驗之Code Copilot AI編程大模型

一、前言GPT-4o&#xff08;"o"代表"全能"&#xff09;具備處理各種文本、聲音和圖像資料的能力&#xff0c;能夠輸出多種格式的文本、聲音和圖像。GPT-4o 的推出標志著 AI 技術的重大突破。它不再局限于單一媒介&#xff0c;而是首次實現了文本、語音和圖…