2023年的深度學(xué)習(xí)入門指南(2) - 給openai API寫前端
上一篇我們說了,目前的大規(guī)模預(yù)訓(xùn)練模型技術(shù)還避免不了回答問題時(shí)出現(xiàn)低級(jí)錯(cuò)誤。
但是其實(shí),人類犯的邏輯錯(cuò)誤也是層出不窮。
比如,有人就認(rèn)為要想學(xué)好chatgpt,就要先學(xué)好Python。
其隱含的推理過程可能是這樣的:
-
TensorFlow需要使用Python
-
PyTorch需要使用Python
-
Scikit-Learn需要使用Python
-
Hugging Face需要使用Python
… -
它們都是機(jī)器學(xué)習(xí)相關(guān)的庫,它們都使用Python
=>
- chatgpt也是機(jī)器學(xué)習(xí)相關(guān)的庫,所以也需要使用Python
所以,需要學(xué)習(xí)Python
誠然,使用傳統(tǒng)深度學(xué)習(xí)框架基本上都要跟Python打交道。而且Python只是一層皮,為了訓(xùn)練和推理更頭疼的是安裝各種加速框架和庫,比如CUDA和cudnn等庫。而且這些庫一般都不支持最新的Python版本和CUDA版本。為了避免庫打架,基本針對(duì)每一種主要框架就要搭一套Python虛擬環(huán)境。這些框架之間的CUDA庫的需求不同的話還得裝多個(gè)版本。
甚至如果你單機(jī)用的是相對(duì)小眾的設(shè)備比如3090,4090之類的卡,通用的框架庫還不見得支持你的高端設(shè)備,還得自己從源碼重新編譯一個(gè)。
如果你還要搞跟CV相關(guān)的算法的話,那么你要裝的庫更多,很多本地庫還沖突。還要安裝適合CPU的并行計(jì)算庫和數(shù)學(xué)庫。Intel的相對(duì)成熟,如果你還買的是AMD的CPU,那繼續(xù)適配吧。
諸如此類。
但是,現(xiàn)在所有的計(jì)算都是跑在openai的服務(wù)器上,你不管懂多少TensorFlow, PyTorch, JAX, Torch Dynamo, Torch Inductor, Trition, OpenMP, CUDA, Vulkan, TVM, LLVM MLIR等等通天本領(lǐng)都用不上。
現(xiàn)在能做的事情,基本上就是按照openai API的格式拼幾個(gè)字符串和json串,發(fā)給openai的服務(wù)器,然后解析從openai服務(wù)器返回的狀態(tài)碼和結(jié)果的json串。
沒錯(cuò),這跟深度學(xué)習(xí)框架沒有任何相似之處,這就是純純的前端干的活兒。任何語言只要有HTTP客戶端庫,再配上一個(gè)輸入框和一個(gè)顯示的文本框,就齊活了。
正因?yàn)橹皇荋TTP API的封裝,所以調(diào)用chatgpt不僅有官方的python庫和node.js庫,還有Java,Go,Kotlin,Swift,R,C#等各種語言的封裝,很多語言還不只一個(gè)版本。不管是在命令行,網(wǎng)頁里,小程序里,Android應(yīng)用,iOS應(yīng)用,Windows桌面應(yīng)用,Unity游戲里等各種客戶端里使用都非常方便。
偽裝成Python庫:10行搞定一切
openai將它們的API封裝在了一個(gè)Python庫里面,我們可以像調(diào)用Python庫一樣去調(diào)用。這樣也是有意義的,可以用來跟本地的其他框架進(jìn)行協(xié)作。
安裝老一套,pip:pip install openai
不需要conda,沒有版本的強(qiáng)需求。不需要CUDA,不需要MKL,Windows下不需要MinGW,… :)
然后去openai注冊(cè)一個(gè)API key。
import openai
openai.api_key = '你的API key'
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": "生成用Python調(diào)用openai API的示例代碼"}
]
)
print(completion.choices[0].message.content)
然后運(yùn)行就可以了,只要你的網(wǎng)絡(luò)連接沒問題,就可以像網(wǎng)頁一樣看到chatgpt一樣的結(jié)果了。
運(yùn)行結(jié)果如下:
import openai
import pprint
# 設(shè)置你的 API 密鑰,這里需要調(diào)用 API 才能正常運(yùn)行
openai.api_key = "YOUR_API_KEY"
# 創(chuàng)建一個(gè) OpenAI GPT-3 模型實(shí)例
model_engine = "text-davinci-002"
model = openai.Model(model_engine)
# 定義一個(gè)prompt(即生成文本的起點(diǎn))
prompt = "The quick brown fox"
# 調(diào)用 openai API 生成文本
response = model.generate(
prompt=prompt,
temperature=0.5,
max_tokens=100,
n=1,
stop=None,
)
# 將返回的結(jié)果打印出來
pprint.pprint(response.choices[0].text)
截至本文寫作的2023年4月4日,gpt-3.5-turbo是最強(qiáng)大而且最劃算的模型。其它的API,模型和方法,效果和費(fèi)用都不如這一個(gè)。所以,要不要學(xué)習(xí)用text-davinci-003等其它模型全看興趣了,它們不能提供更強(qiáng)的能力了。
有的同學(xué)表示,上面的語句看不懂,怎么辦?
太好辦了,把上面的代碼發(fā)給openai的API,讓chatgpt來給我們講解:
import openai
openai.api_key = '你的API key'
str1 = """
解釋一下下面的代碼是作什么用的?
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": "生成用Python調(diào)用openai API的示例代碼"}
]
)
print(completion.choices[0].message.content)
"""
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": str1}
]
)
print(completion.choices[0].message.content)
這是openai api給我們返回的講解:
這段代碼是使用OpenAI API中的Chat API來生成一個(gè)自然語言對(duì)話的示例。它指定了要使用的訓(xùn)練模型為"gpt-3.5-turbo",并且設(shè)置了一個(gè)包含一條用戶消息的對(duì)話歷史記錄。這個(gè)對(duì)話歷史記錄是一個(gè)字典,其中包含兩個(gè)鍵:"role"和"content"。這個(gè)對(duì)話歷史記錄被傳遞
給ChatCompletion.create()方法,以生成一條完整的對(duì)話。最后,代碼打印出了OpenAI返回的答復(fù)的內(nèi)容。
具體玩法的例子
跨語言程序翻譯
比如我們想把剛才調(diào)用openai的代碼翻譯成kotlin的,以便在Android應(yīng)用里用。就讓openai API幫我們翻譯:
import openai
openai.api_key = '你的API Key'
str1 = """
翻譯成Kotlin
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": "生成用Python調(diào)用openai API的示例代碼"}
]
)
print(completion.choices[0].message.content)
"""
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": str1}
]
)
print(completion.choices[0].message.content)
生成代碼如下:
var completion = ChatCompletion.create(
model = "gpt-3.5-turbo",
messages = listOf(
Message(role = "user", content = "生成用Python調(diào)用openai API的示例代碼")
)
)
println(completion.choices[0].message.content)
翻譯成Swift,大家自己改語句,我就不寫了,結(jié)果如下:
var completion = try! openai.ChatCompletion.create(
model: "gpt-3.5-turbo",
messages: [
.init(role: "user", content: "生成用Python調(diào)用openai API的示例代碼")
]
)
print(completion.choices[0].message.content)
讓它幫我們翻譯成Go語言:
package main
import (
"fmt"
"github.com/openai/go-api"
)
func main() {
client := openai.NewClient("YOUR_API_KEY")
prompt := []openai.ChatMessage{
{Role: "user", Text: "生成用Python調(diào)用openai API的示例代碼"},
}
chatOpts := &openai.ChatOpts{
Model: "davinci",
Prompt: &prompt,
MaxTokens: openai.Int(64),
Temperature: openai.Float32(0.6),
}
resp, err := client.CreateChat(chatOpts)
if err != nil {
fmt.Println(err)
return
}
message := resp.Choices[0].Text
fmt.Println(message)
}
我們發(fā)現(xiàn),Go的翻譯它用的是老模型davnici,我們教它一下新的python API用法,然后讓它翻譯成Go的:
str1 = """
調(diào)用openai chat api的官方例子如下:
import openai
openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Who won the world series in 2020?"},
{"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
{"role": "user", "content": "Where was it played?"}
]
)
chat api的API地址為:https://api.openai.com/v1/chat/completions
請(qǐng)根據(jù)此生成用Go語言調(diào)用的例程
"""
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": str1}
]
)
print(completion.choices[0].message.content)
```python
生成的代碼結(jié)果如下:
```go
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type Message struct {
Role string `json:"role"`
Content string `json:"content"`
}
type ChatRequest struct {
Model string `json:"model"`
Messages []Message `json:"messages"`
}
type ChatResponse struct {
ID string `json:"id"`
Created int64 `json:"created"`
Model string `json:"model"`
Object string `json:"object"`
}
func main() {
url := "https://api.openai.com/v1/chat/completions"
req := ChatRequest{
Model: "gpt-3.5-turbo",
Messages: []Message{
{Role: "system", Content: "You are a helpful assistant."},
{Role: "user", Content: "Who won the world series in 2020?"},
{Role: "assistant", Content: "The Los Angeles Dodgers won the World Series in 2020."},
{Role: "user", Content: "Where was it played?"},
},
}
payloadBytes, err := json.Marshal(req)
if err != nil {
fmt.Println("Error:", err)
return
}
body := bytes.NewReader(payloadBytes)
req, err := http.NewRequest("POST", url, body)
if err != nil {
fmt.Println("Error:", err)
return
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Bearer [API_KEY]") // Replace [API_KEY] with your OpenAI API key
client := http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error:", err)
return
}
defer resp.Body.Close()
var chatResp ChatResponse
decoder := json.NewDecoder(resp.Body)
if err := decoder.Decode(&chatResp); err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("ID:", chatResp.ID)
}
修復(fù)代碼bug
還是老辦法,prompt就寫修復(fù)代碼bug:
str1 = """
修復(fù)下面代碼的bug:
```javas
private StringBuffer encoder(String arg) {
if (arg == null) {
arg = "";
}
MessageDigest md5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
md5.update(arg.getBytes(SysConstant.charset));
} catch (Exception e) {
e.printStackTrace();
}
return toHex(md5.digest());
}
“”"
completion = openai.ChatCompletion.create(
model=“gpt-3.5-turbo”,
messages=[
{“role”: “user”, “content”: str1}
]
)
print(completion.choices[0].message.content)
輸出如下:
===========================================
以下是修復(fù)后的代碼:
```java
private StringBuffer encoder(String arg) {
if (arg == null) {
arg = "";
}
StringBuffer hexString = new StringBuffer();
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] messageDigest = md5.digest(arg.getBytes(StandardCharsets.UTF_8));
for (byte b : messageDigest) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return hexString;
}
修復(fù)的bug如下:
- 使用了
StringBuffer
,在多線程下是線程安全的; - 在處理字節(jié)數(shù)組轉(zhuǎn)換為16進(jìn)制字符串時(shí),采用了更簡(jiǎn)單的方式;
- 采用了Java 7中引入的
StandardCharsets.UTF_8
替代原有的SysConstant.charset
,使用Java標(biāo)準(zhǔn)庫中的字符集; - 捕捉NoSuchAlgorithmException異常,以免發(fā)生錯(cuò)誤。
==========================================
寫摘要
還是老辦法,寫prompt.
str1 = """
下面一段文字的主要觀點(diǎn)是什么:
I have a dream that one day this nation will rise up and live out the true meaning of its creed: "We hold these truths to be self-evident, that all men are created equal."
I have a dream that one day on the red hills of Georgia, the sons of former slaves and the sons of former slave owners will be able to sit down together at the table of brotherhood.
I have a dream that one day even the state of Mississippi, a state sweltering with the heat of injustice, sweltering with the heat of oppression, will be transformed into an oasis of freedom and justice.
I have a dream that my four little children will one day live in a nation where they will not be judged by the color of their skin but by the content of their character.
I have a dream today!
I have a dream that one day, down in Alabama, with its vicious racists, with its governor having his lips dripping with the words of "interposition" and "nullification" -- one day right there in Alabama little black boys and black girls will be able to join hands with little white boys and white girls as sisters and brothers.
I have a dream today!
I have a dream that one day every valley shall be exalted, and every hill and mountain shall be made low, the rough places will be made plain, and the crooked places will be made straight; "and the glory of the Lord shall be revealed and all flesh shall see it together."
"""
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": str1}
]
)
print(completion.choices[0].message.content)
輸出如下:
The main point of this text is that the speaker has a dream for racial equality and justice, where people of different races can come together, and discrimination is eradicated.
還可以找關(guān)鍵字:
str1 = """
下面一段話的關(guān)鍵字:
We introduce LLaMA, a collection of foundation language models ranging from 7B to 65B parameters. We train our models on trillions of tokens, and show that it is possible to train state-of-the-art models using publicly available datasets exclusively, without resorting to proprietary and inaccessible datasets. In particular, LLaMA-13B outperforms GPT-3 (175B) on most benchmarks, and LLaMA- 65B is competitive with the best models, Chinchilla-70B and PaLM-540B. We release all our models to the research community.
"""
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": str1}
]
)
print(completion.choices[0].message.content)
輸出如下:
LLaMA, language models, parameters, trillions of tokens, state-of-the-art models, publicly available datasets, GPT-3, benchmarks, Chinchilla-70B, PaLM-540B, research community.
數(shù)學(xué)推導(dǎo)
比如我們給出皮亞諾公理的5條公理,讓gpt 3.5幫我們定義加法和乘法兩種操作:
str1 = """
根據(jù)下面5條公理,定義加法和乘法兩種操作:
第一,0是一個(gè)自然數(shù)
第二,任何自然數(shù)n都有一個(gè)自然數(shù)Suc(n)作為它的后繼
第三,0不是任何自然數(shù)的后繼
第四,后繼函數(shù)是單一的,即,如果Suc(m)=Suc(n),則m=n.
第五,令Q為關(guān)于自然數(shù)的一個(gè)性質(zhì)。如果0具有性質(zhì)Q,并且 如果自然數(shù)n具有性質(zhì)Q,則Suc(n)也具有性質(zhì)Q,那么所有自然數(shù)n都有性質(zhì)Q
"""
completion = openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[
{"role": "user", "content": str1}
]
)
print(completion.choices[0].message.content)
輸出如下:
加法定義:
對(duì)于任何自然數(shù)n,定義加法操作+如下:
n+0=n (根據(jù)第一公理)
n+Suc(m)=Suc(n+m) (根據(jù)第二、四公理)
乘法定義:
對(duì)于任何自然數(shù)n,定義乘法操作*如下:
n*0=0 (根據(jù)第一公理)
n*Suc(m)=n*m+n (根據(jù)第二、四公理)
補(bǔ)全API - Completion
補(bǔ)全API的能力本質(zhì)上跟Chat API沒有太大的區(qū)別。因?yàn)椴挥弥噶罱巧?,比起Chat API能夠更簡(jiǎn)潔一點(diǎn)。
我們來看一個(gè)例子:
code1 = '請(qǐng)給林肯傳記列一個(gè)提綱'
completion = openai.Completion.create(
model="text-davinci-003",
prompt=code1,
max_tokens=2048,
temperature=1
)
print(completion.choices[0].text)
輸出如下:
一、林肯的童年經(jīng)歷
(1)出身環(huán)境
(2)家庭教育和兄弟姐妹
(3)小時(shí)候的生活
二、林肯的教育發(fā)展
(1)接受過的教育
(2)取得的成就
三、林肯的政治生涯
(1)職務(wù)和重大成果
(2)有影響力的言論
四、林肯受追捧的原因
(1)實(shí)踐詮釋真理
(2)立場(chǎng)穩(wěn)健無私
(3)擁護(hù)奴隸解放
text-davinci-003是基于最新的gpt 3.5的,能力較強(qiáng)而速度較慢的一個(gè)模型,如果想用更快但是質(zhì)量差一點(diǎn)的可以采用更弱一些的基于gpt 3的text-curie-001,text-babbage-001和text-ada-001。他們的能力依次遞減。
在目前這個(gè)時(shí)刻,text-davinci-003是比gpt-3.5-turbo要貴一點(diǎn)的,請(qǐng)注意關(guān)注下預(yù)算。
另外,gpt4目前只有在Chat API上才有。所以就是讓大家知道有Completion這個(gè)API就好。目前不管是能力上(gpt4)還是預(yù)算上(gpt-3.5-turbo)都是Chat API占優(yōu)。文章來源:http://www.zghlxwxcb.cn/news/detail-401766.html
小結(jié)
從目前這個(gè)時(shí)點(diǎn)看,基本上只學(xué)習(xí)ChatCompletion一個(gè)API就足夠用了。功能全靠Prompt來指定。文章來源地址http://www.zghlxwxcb.cn/news/detail-401766.html
到了這里,關(guān)于2023年的深度學(xué)習(xí)入門指南(2) - 給openai API寫前端的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!