
譯者 | 陳峻
審校 | 重樓
本文將向你介紹OpenAI新發(fā)布的兩個開源模型--gpt-oss-120b和gpt-oss-20b,它們的特點,以及在何種場景下該使用哪個模型。
近期,OpenAI發(fā)布了兩個開源的大語言模型(LLM)--gpt-oss-120b和gpt-oss-20b。它們是自GPT-2以來,由OpenAI第一個公開許可的LLM。其旨在創(chuàng)建最好、最先進的、供推理和工具使用的模型。通過開源gpt-oss,OpenAI允許人們在Apache 2.0的范圍內,自由地使用和適配。當然,這兩種模式也考慮了專業(yè)個性化,以及定制到本地和上下文任務的民主化方法。
在本文指南中,我們將介紹如何獲取gpt-oss-120b和gpt-oss-20b服務,以及在何種場景下使用哪個模型。
gpt-oss的特別之處
OpenAI本次新開源的模型是自GPT-2以來最強大的公共模型。其先進之處主要體現(xiàn)在:
- 開放的Apache 2.0許可證:gpt-oss的各種模型不但完全開源,并且是根據(jù)Apache 2.0許可證提供授權的。這意味著,它們沒有任何copyleft限制,開發(fā)人員可以將其用于研究或商業(yè)產(chǎn)品,且無需許可費或源代碼義務。
- 可配置的推理水平:gpt-oss獨特的功能在于用戶可以輕松地將模型的推理能力配置為:低、中或高。這是速度與“思考”深度的權衡。使用“淺推理”和“深度推理”分別會讓模型在回答之前進行少量與深度的“思考”。
- 全思考鏈(Chain-of-Thought)訪問:與許多封閉模型不同,gpt-oss展示了其內部推理。它有一個默認的分析輸出,即推理步驟通道,以指向最終答案通道。用戶和開發(fā)人員可以檢查或過濾輸出部分,以調試或信任模型的推理。
- 原生代理功能:gpt-oss模型建立在代理工作流之上。它們是為遵循指令而構建的,而且在“思考”中使用了工具的原生支持。
模型概述和架構
這兩個gpt-oss模型都基于Transformer網(wǎng)絡,采用了專家混合(Mixture-of-Experts,MoE)設計。在MoE中,只有完整參數(shù)(即“專家”)的子集才對于每個輸入的token有效,從而減少了計算。我們來看一組數(shù)字:
- gpt-oss-120b的總參數(shù)量為1170億個(36層)。它使用了128個專家子網(wǎng)絡,每個token都有4個活躍的專家,也就是說每個token能生成51億個活躍參數(shù)。
- gpt-oss-20b的總參數(shù)量為210億個(24層),它有32個專家(4個活躍),每個token產(chǎn)生約36億個活躍參數(shù)。同時,該架構還包括了一些高級功能,例如:所有注意力層(attention layer)都使用旋轉位置嵌入(Rotary Positional Embeddings,RoPE)來處理過長的上下文(最多128,000個token),以便注意力本身在全局滑動窗口和128 token的滑動窗口之間交替進行。該設計類似于GPT-3。
此外,這些模型使用了大小為8的分組多查詢注意力,以節(jié)省內存,同時也保持了快速推理能力。由于其激活函數(shù)是SwiGLU,因此所有專家權重都被量化為4位的MXFP4格式,以允許大型模型適配80GB GPU,讓小型模型適配16GB,而不會造成重大的準確性損失。
下表總結了其核心規(guī)格參數(shù):
模型 | 層 | 總參數(shù) | 活躍參數(shù)/token | 專家(總計/活躍) | 上下文 |
gpt-oss-120b | 36 | 117B | 5.1B | 128 / 4 | 128K |
gpt-oss-20b | 24 | 21B | 36B | 32/4 | 128K |
技術規(guī)格和許可
- 硬件要求:gpt-oss-120b需要高端GPU(約80-100 GB VRAM),并在單個80 GB A100/H100級GPU或多GPU的設置上運行。而gpt-oss-20b相對較輕,即使在筆記本電腦或蘋果Silicon上也能以約16 GB VRAM運行。同時,這兩種型號都支持128K token的上下文,非常適合冗長的文檔,以及密集型計算。
- 量化和性能:這兩種型號都使用4位的MXFP4作為默認值,其有助于減少內存的使用,并加快推理速度。當然,如果沒有兼容的硬件,它們會回落到16位,并且需要約48 GB供給gpt-oss-20b。此外,使用FlashAttention等可選的高級內核,也可以進一步提高計算速度。
- 許可證和使用:基于Apache 2.0發(fā)布,這兩種型號都可以被自由地使用、修改和分發(fā),甚至用于商業(yè)用途,而無版權或代碼共享的要求,更無API費用或許可證限制。
技術規(guī)格 | gpt-oss-120b | gpt-oss-20b |
總參數(shù) | 1170億 | 210億 |
每個token的活躍參數(shù) | 51億 | 36億 |
架構 | 帶有128專家的MoE(4個活躍/token) | 帶有32專家的MoE(4個活躍/token) |
Transformer塊 | 36層 | 24層 |
上下文窗口 | 128,000個token | 128,000個token |
內存要求 | 80 GB(適合單個H100 GPU) | 16GB |
安裝和設置過程
下面我們來看看如何上手使用gpt-oss:
Hugging Face Transformers:請安裝其最新的庫,并直接加載模型。以下安裝命令是必要的先決條件:
pip install --upgrade accelerate transformers以下代碼可從Hugging Face hub處下載所需的模型。
from transformers import AutoTokenizer, AutoModelForCausalLM
tokenizer = AutoTokenizer.from_pretrained("openai/gpt-oss-20b")
model = AutoModelForCausalLM.from_pretrained(
"openai/gpt-oss-20b", device_map="auto", torch_dtype="auto")下載模型后,你可以使用以下方式進行測試:
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Explain why the sky is blue."}
]
inputs = tokenizer.apply_chat_template(
messages, add_generation_prompt=True, return_tensors="pt"
).to(model.device)
outputs = model.generate(**inputs, max_new_tokens=200)
print(tokenizer.decode(outputs[0]))此設置可從OpenAI指南中獲得,并在任何GPU上運行。為了在NVIDIA A100/H100卡上獲得最佳速度,請安裝triton內核,以使用MXFP4;否則該模型將會在內部使用16位。
vLLM:對于高吞吐量或多GPU服務,你可以使用vLLM庫。OpenAI在2x H100s上可以實現(xiàn),你可以使用以下命令安裝vLLM:
pip install vllm接著你可以通過以下命令啟動服務器:
vllm serve openai/gpt-oss-120b --tensor-parallel-size 2或者在Python中,使用:
from vllm import LLM
llm = LLM("openai/gpt-oss-120b", tensor_parallel_size=2)
output = llm.generate("San Francisco is a")
print(output)這其實是在Hopper GPU上使用優(yōu)化的注意力內核。
Ollama(Mac/Windows上的本地):Ollama是本地聊天服務器的turnkey。安裝Ollama后,只需運行:
ollama pull gpt-oss:20b
ollama run gpt-oss:20b這將下載(量化)模型并啟動用戶聊天界面。Ollama會默認自動應用“harmony”格式的聊天模板。你也可以通過API調用它。例如,使用Python和OpenAI SDK指向Ollama的終端:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
response = client.chat.completions.create(
model="gpt-oss:20b",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Explain what MXFP4 quantization is."}
]
)
print(response.choices[0].message.content)它會像官方API一樣,將提示詞發(fā)送給本地gpt-oss模型。
Llama.cpp(CPU/ARM):提供預構建的GGUF版本(例如,ggml-org/GPT-Oss-120b-GGUF on Hugging Face)。安裝llama.cpp后,你可以在本地構建服務模型:
# macOS:
brew install llama.cpp
# Start a local HTTP server for inference:
llama-server -hf ggml-org/gpt-oss-120b-GGUF -c 0 -fa --jinja --reasoning-format none然后以相同的格式將聊天消息發(fā)送到http://localhost:8080。此選項允許在具有JIT或Vulkan支持的CPU或GPU-agnostic的環(huán)境中運行。
總體而言,gpt-oss模型可以與最常見的框架一起使用。上述方法(如:Transformers、vLLM、Ollama、llama.cpp)涵蓋了桌面和服務器設置。你也可以進行混合配置。例如,運行一個用于快速推理的設置(如:在GPU上的vLLM)和另一個用于設備測試的設置(如:Ollama或llama.cpp)。
實際操作演示部分
任務 1:推理任務
提示詞:選擇與第三個術語相關的選項,就像第二個術語與第一個術語相關的方式一樣。
IVORY : ZWSPJ :: CREAM : ?
- NFDQB
- SNFDB
- DSFCN
- BQDZL
import os
os.environ['HF_TOKEN'] = 'HF_TOKEN'
from openai import OpenAI
client = OpenAI(
base_url="https://router.huggingface.co/v1",
api_key=os.environ["HF_TOKEN"],
)
completion = client.chat.completions.create(
model="openai/GPT-Oss-20b", # openai/GPT-Oss-120b Change to use 120b model
messages=[
{
"role": "user",
"content": """Select the option that is related to the third term in the same way as the second term is related to the first term.
IVORY : ZWSPJ :: CREAM : ?
A. NFDQB
B. SNFDB
C. DSFCN
D. BQDZL
"""
}
],
)
# Check if there's content in the main content field
if completion.choices[0].message.content:
print("Content:", completion.choices[0].message.content)
else:
# If content is None, check reasoning_content
print("Reasoning Content:", completion.choices[0].message.reasoning_content)
# For Markdown display in Jupyter
from IPython.display import display, Markdown
# Display the actual content that exists
content_to_display = (completion.choices[0].message.content or
completion.choices[0].message.reasoning_content or
"No content available")gpt-oss-120b的響應為:
Content: **Answer: C. DSFCN**
1
Answer: C. DSFCN
display (Markdown (content_to_display))
gpt-oss-20b的回應為:
display (Markdown (content_to_display))
→ Letters of CREAM: C=3, R=18, E=5, A=1, M=13.
Option A: NFDQB: N=14, F=6, D=4, Q=17, B=2. Differences: +11, -12, -1, +16, -11? Let's compute: 3->14 diff +11.
18->6 diff -12 or +14 mod 26. 5->4 diff -1. 1->17 diff +16. 13->2 diff -11 or +15 mod 26.
Option B: SNFDB: S=19, N=14, F=6, D=4, B=2. Diffs: +16, -4, +1, +3, -11? Actually 1->? Wait 1 is A -> D=4 diff +3. 13->2 diff -11.
Option C: DSFCN: D=4, S=19, F=6, C=3, N=14. Diffs: +1, -4? 18->19 +1? Wait from R=18 to S=19 diff +1. 5->6 +1. 1->3 +2. 13->14 +1. So diff pattern from CREAM: +1, +1, +1, +2, +1? Hmm.
Option D: BQDZL: B=2, Q=17, D=4, Z=26, L=12. Diffs: -1? 3->2-1. 18->17 - 1. 5->4 -1. 1->26 -? 1->26 diff+25 or
1 but need wrap: 1 to 26 is -1 mod 26? Actually 26-1=25; but shift -1? 13->12 -1. So pattern differences:
1,-1,-1,-1,-1. That looks like constant shift -1. Wait check: A-> difference of -1? But from A to Z one position back yields Z. So -1 shift for each letter.
But CREAM to BQDZL: C(3)->B(2) diff -1; R(18)->Q(17) diff -1; E(5)->D(4) diff -1; A(1)->Z(26) diff -1; M(13)-
>L(12) diff -1. Yep exactly each letter minus 1 circularly. So mapping from IVORY to ZWSPJ: Let's check if shift is also -1 for all letters? IVORY: I(9)->Z(26) diff -? 9-1=8 which is H, not Z. So not -1. Let's try shift +? but maybe we mis-evaluated earlier differences incorrectly? Let's compute mapping of letters of IVORY to ZWSPJ if shift is +? compute 9 > 26: difference +17. 22 ->23: +1. 15 ->19: +4. 18->16: -2. 25->10: -15 or +11. So not constant.
But mapping for CREAM to BQDZL is constant -1. Could that be the same rule that applied to IVORY? Let's see if maybe we mis-check: maybe we should shift each letter of IVORY +? to get ZWSPJ. Check if shift is maybe +10?
9+10=19 -> S, not Z. Maybe shift is +? maybe it's variable: first letter shift by +17, second +1, etc. Might correspond to the positions of C and D? Maybe shift pattern equal to letters of "IRIS"? Hard.
But maybe we mis-evaluated mapping: Let's just brute force compute if there's any simple transformation for
IVORY to ZWSPJ that could also apply to CREAM making one of options. Because four options: NFDOB (option
A) etc. Maybe only one will match a pattern that also holds for IVORY->ZWSPJ.
Maybe we need to deduce mapping from the two words: find the key that transforms first to second. Could be a Caesar shift based on some rule like shift each letter by number of letters same as preceding letter's position difference? For example: I shift by something, produce Z. Let's see I->Z: difference 17. Maybe shift equals difference between l's position in alphabet and length of word? 9-5=4? Not 17. difference between number of letters before I? No.
Maybe mapping uses the second word's letters as "reference" like "Z" is the 26th letter which equals sum of I (9) +
V 22) + 0(15) + R18) + Y25) = 9+22+15+18+25=89; 89 mod 26 = 11? not 26.比較分析
gpt-oss-120B正確地識別了類比中的相關模式,并通過深思熟慮的推理選擇了選項C。因為它有條不紊地解釋了單詞對之間的字符轉換,因此獲得了正確的映射。另一方面,gpt-oss-20B未能在此任務上產(chǎn)生任何結果,則可能是因為輸出token的限制,也就揭示了輸出長度的局限性,以及計算效率的低下??傮w而言,gpt-oss-120B能夠更好地管理符號推理,具有更多的控制和準確性??梢姡瑢τ诖祟惿婕暗秸Z言類比的推理任務而言,gpt-oss-120B比gpt-oss-20B更可靠。
任務2:代碼生成
提示詞:給定兩個大小分別為m和n的排序數(shù)組nums1和nums2,返回兩個排序數(shù)組的中位數(shù)。
在C++中,總體運行時復雜度應該是O(log(m+n))。
示例1:
輸入:nums1 = [1,3],nums2 = [2]
輸出:2.00000
解釋:合并數(shù)組=[1,2,3],中位數(shù)為2。
示例2:
輸入:nums1 = [1,2],nums2 = [3,4]
輸出:2.50000
解釋:合并數(shù)組=[1,2,3,4],中位數(shù)為(2 + 3)/2 = 2.5。
約束:
nums1.length==m
nums2.length==n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i],nums2[i] <= 106
import os
from openai import OpenAI
client = OpenAI(
base_url="https://router.huggingface.co/v1",
api_key=os.environ["HF_TOKEN"],
)
completion = client.chat.completions.create(
model="openai/GPT-Oss-120b", # openai/GPT-Oss-20b change to use 20b model
messages=[
{
"role": "user",
"content": """Given two sorted arrays nums1 and nums2 of size m and n respectively, return the median of the two sorted arrays.
The overall run time complexity should be O(log (m+n)) in C++.
Example 1:
Input: nums1 = [1,3], nums2 = [2]
Output: 2.00000
Explanation: merged array = [1,2,3] and median is 2.
Example 2:
Input: nums1 = [1,2], nums2 = [3,4]
Output: 2.50000
Explanation: merged array = [1,2,3,4] and median is (2 + 3) / 2 = 2.5.
Constraints:
nums1.length == m
nums2.length == n
0 <= m <= 1000
0 <= n <= 1000
1 <= m + n <= 2000
-106 <= nums1[i], nums2[i] <= 106
"""
}
],
)
# Check if there's content in the main content field
if completion.choices[0].message.content:
print("Content:", completion.choices[0].message.content)
else:
# If content is None, check reasoning_content
print("Reasoning Content:", completion.choices[0].message.reasoning_content)
# For Markdown display in Jupyter
from IPython.display import display, Markdown
# Display the actual content that exists
content_to_display = (completion.choices[0].message.content or
completion.choices[0].message.reasoning_content or
"No content available")gpt-oss-120b的響應為:
include <bits/stdc++.h>
using namespace std;
class Solution {
public:
double findMedianSortedArrays(const vector<int>& nums1,
const vector<int>& nums2) {
// Let A be the shorter array.
const vector<int>* A = &nums1;
const vector<int>* B = &nums2;
if (A->size() > B->size()) swap(A, B); // now |A| ≤ |B|
int m = A->size();
int n = B->size();
int total = m + n;
int half = (total + 1) / 2; // size of left part
int low = 0, high = m; // we search over number of elements taken from A
while (low <= high) {
int i = (low + high) / 2; // elements from A on the left side
int j = half - i; // must come from B
// Edge handling: use infinities for out?of?range indices
int a_left = (i == 0 ? INT_MIN : (*A)[i - 1]);
int a_right = (i == m ? INT_MAX : (*A)[i]);
int b_left = (j == 0 ? INT_MIN : (*B)[j - 1]);
int b_right = (j == n ? INT_MAX : (*B)[j]);
if (a_left > b_right) { // i too large
high = i - 1;
} else if (b_left > a_right) { // i too small
low = i + 1;
} else { // correct split
int max_left = max(a_left, b_left);
if (total % 2 == 1) // odd
return static_cast<double>(max_left);
int min_right = min(a_right, b_right);
return (max_left + min_right) / 2.0;
}
}
// The code never reaches here because the constraints guarantee at least one element.
return 0.0;
}
};
/* Example usage
int main() {
Solution s;
vector<int> a = {1, 3};
vector<int> b = {2};
cout << fixed << setprecision(5) << s.findMedianSortedArrays(a, b) << endl; // 2.00000
a = {1,2};
b = {3,4};
cout << fixed << setprecision(5) << s.findMedianSortedArrays(a, b) << endl; // 2.50000
}gpt-oss-20b的響應為:
# Reference Implementation (C++17)
include <bits/stdc++.h>
using namespace std;
class Solution {
public:
double findMedianSortedArrays(vector<int>& nums1,
vector<int>& nums2) {
// Ensure nums1 is the shorter array
if (nums1.size() > nums2.size())
return findMedianSortedArrays(nums2, nums1);
int m = nums1.size();
int n = nums2.size();
int low = 0, high = m;
int halfLen = (m + n + 1) / 2; // size of left part
while (low <= high) {
int i = (low + high) / 2; // partition in nums1
int j = halfLen - i; // partition in nums2
// i too small - must move right
if (i < m && nums2[j-1] > nums1[i])
low = i + 1;
// i too big - must move left
else if (i > 0 && nums1[i-1] > nums2[j])
high = i - 1;
else {
// correct partition found
int maxLeft;
if (i == 0)
maxLeft = nums2[j-1];
else if (j == 0)
maxLeft = nums1[i-1];
else
maxLeft = max(nums1[i-1], nums2[j-1]);
// odd total, median is maxLeft
if ((m + n) % 2 == 1)
return static_cast<double>(maxLeft);
// even total, need minRight as well
int minRight;
if (i == m)
minRight = nums2[j];
else if (j == n)
minRight = nums1[i];
else
minRight = min(nums1[i], nums2[j]);
return (maxLeft + minRight) / 2.0;
}
}
// Should never reach here for valid input
return 0.0;
}
};
/* Example usage:
int main() {
Solution s;
vector<int> a = {1, 3};
vector<int> b = {2};
cout << fixed << setprecision(5) << s.findMedianSortedArrays(a, b) << endl; // 2.00000
}比較分析
gpt-oss-120B準確地完成了類比,選擇了選項C,并通過成功地識別字母替換模式,顯示了強有力的理由。該模型在處理字母振蕩的轉變和跟蹤事物之間的關系方面,顯示了良好的推理。與之對比,gpt-oss-20B甚至無法完成任務。該模型超過了輸出token的限制,沒有返回答案。這表明gpt-oss-20B在資源使用或處理提示方面效率低下??傮w而言,gpt-oss-120B在結構推理任務中表現(xiàn)得更好,這使得它比gpt-oss-20B更擅長與符號類比相關的任務。
模型選擇指南
在120B和20B模型之間如何進行選擇,完全取決于項目需求或我們正在處理的任務。通常:
- gpt-oss-120b:是一種大功率模型,可將其用于較為困難的推理任務、復雜的代碼生成、數(shù)學問題解決或特定領域的問答。它的性能接近OpenAI的o4-mini模型。因此,它需要一個具有80GB以上 VRAM的大型GPU來運行,并且能在視分步推理至關重要的基準和長形式(long-form)任務中表現(xiàn)出色。
- gpt-oss-20b:是一個針對效率優(yōu)化的“苦干”模型。在許多基準測試中,它與OpenAI的o3-mini的質量相匹配,但可以在單個16GB VRAM上運行。當你需要快速的設備響應助手、低延遲聊天機器人、或使用網(wǎng)絡搜索、及Python調用的工具時,請選擇20B。它非常適合概念驗證、移動/邊緣應用、或硬件受限的場景使用。在許多情況下,20B模型的回答已足夠好。例如,它在某項困難的數(shù)學競賽任務中的得分約為96%,幾乎與120B相當。
性能基準和比較
在標準化基準方面,OpenAI的各個gpt-oss可以共享結果。目前,120B模型正在不斷迭代。它在艱難的推理和知識任務上的得分已高于20B模型,雖然目前兩者仍各有千秋。
基準 | gpt-oss-120b | gpt-oss-20b | 開放AI o3 | OpenAI o4-mini |
MMLU | 90.0 | 85.3 | 93.4 | 93.0 |
GPQA Diamond | 80.1 | 71.5 | 83.3 | 81.4 |
Humanity’s Last Exam | 19.0 | 17.3 | 24.9 | 17.7 |
AIME 2024 | 96.6 | 96.0 | 95.2 | 98.7 |
AIME 2025 | 97.9 | 98.7 | 98.4 | 99.5 |

來源:ChatGPT

來源:ChatGPT
用例和應用
以下是gpt-oss的一些典型用例場景:
- 內容生成和重寫:生成或重寫文章、故事或營銷文案。gpt-oss模型可以在寫作前描述他們的思維過程,并幫助作家和記者創(chuàng)建更好的內容。
- 輔導和教育:可以演示描述概念的不同方式,一步一步地解決問題,并為教育應用或輔導工具和醫(yī)學提供反饋。
- 代碼生成:可以很好地生成代碼、調試代碼或解釋代碼。gpt-oss模型也可以在內部運行工具,允許它們輔助開發(fā)任務或作為編碼助手提供幫助。
- 研究協(xié)助:可以總結文檔,回答特定領域的問題,并分析數(shù)據(jù)。gpt-oss的模型也可以針對法律、醫(yī)學或科學等特定研究領域進行微調。
- 自主代理:啟用并使用工具構建帶有自主代理的機器人。這些機器人可以瀏覽網(wǎng)頁、調用API或運行代碼。它們便捷地與代理框架集成,以構建更復雜的基于步驟的工作流。
小結
綜上所述,在OpenAI發(fā)布的兩個開源模型gpt-oss-120b和gpt-oss-20b中,120B模型全面表現(xiàn)優(yōu)秀,特別是在:生成更清晰的內容,解決更難的問題,編寫更好的代碼,并更快地適應研究和自主任務等方面。當然,其短板在于資源利用強度較高,給本地部署帶來了一定挑戰(zhàn)。
譯者介紹
陳峻(Julian Chen),51CTO社區(qū)編輯,具有十多年的IT項目實施經(jīng)驗,善于對內外部資源與風險實施管控,專注傳播網(wǎng)絡與信息安全知識與經(jīng)驗。
原文標題:OpenAI Returns to Open Source: A Complete Guide to gpt-oss-120b and gpt-oss-20b,作者:Vipin Vashisth





































