找回密码
 立即注册
查看: 2692|回复: 0

如何把自有数据接入GPT大模型?

[复制链接]

524

主题

676

回帖

4597

积分

管理员

积分
4597
QQ
发表于 2023-5-29 10:35:28 | 显示全部楼层 |阅读模式
. ~7 v0 R, Z" H5 K* i3 D4 G9 ]
ChatGPT引发了AI革命,大家都想探究如何让它发挥更大价值。
2 Q% b* w. c( M: o  T8 u/ {' Q( n, r' E' z& t! o% g% v' m
以它为代表的大模型并未完全掌握所有专业知识,这也正是我们创业的契机。* t* a+ t3 i8 k& k% h) h2 p

1 a* p$ ]4 ^$ B4 m! d我们应该思考如何让AI在专业领域中释放更大的价值潜能。, l% `4 {$ u2 u# A5 m! Y* R) ]4 _
就像开发者挖掘出某个鲜为人知的资源一样,我们可以开发出AI在特定领域的潜力,从而在市场上脱颖而出。' j' ^# ]1 h0 A5 g% K) [

* Z6 d/ C' e2 s! m( Q5 q以OpenAI的API为例,让大模型支持自己专业领域的知识,有两种方式:微调模型和封装到Prompt。$ V8 J7 r0 n9 s' O4 O/ X

' x% X% D% ^6 j$ u5 z
1 B- Q8 X* V4 r6 b 以OpenAI的API为例,让大模型支持自己专业领域的知识,有两种方式:微调模型和封装到Prompt.png   G0 P: _2 [6 N/ `! k
; K9 H( _1 N& p8 x. I

8 _6 Y; d: j9 f1 m4 ^
+ P5 A7 k9 ^: t! T' x一、微调(Fine-tuning)注入专业领域知识5 m/ Q) W: {) q/ _0 T2 J3 c
微调是在基础大模型训练成熟之后,通过Fine-tuning模式,利用标注数据调整模型参数以适应不同任务需求。. r7 {+ X0 D- g! G( Y- U

" W1 ]: b1 b8 r1 q传统的微调需要做调整损失函数、增加额外层等工作,但自2018年以来,随着预训练模型的体量不断增大,预训练模型Fine-tune所需的硬件和数据需求也在不断增长。此外,下游任务的丰富多样性使得预训练和微调阶段的设计更为复杂。
$ j, f  x# b; ]; C4 R; X+ T( J/ q& u" ]6 _
如今,像GTP-4这样的模型已经采用了一种新的训练模式,即单向语言模型预训练+zero shot prompt/Instruct,它不需要在预训练后进行任务Fine-tuning,而是通过自然语言指令来解决下游任务,这为模型的优化提供了全新的可能性。! W' Y4 G4 H  u* t/ o0 S" F
9 B! S- Y: @$ R- c! o
OpenAI在GPT-4上花了6个月的时间才放出来,是为了使其更安全、更一致,而不是新的专业领域知识的注入,新专业领域知识的注入耗时非常短的,也就根据数据量,几分钟到几小时。
1 t4 ^( o3 S( @# b) u4 T- [) E$ P- V# H
从OpenAI的微调文档 https://platform.openai.com/docs/guides/fine-tuning 可以看出,要准备的数据包含prompt(输入文本)和completion(输出文本)两部分:
) a5 h3 g. ~( |# F- q
0 ^( v* Y9 v6 C" P- b% tprompt是我们给模型的输入文本,它可以是任何文本,例如一个问题、一个描述、一个开头、一个例子等。prompt的作用是告诉模型我们想要完成什么样的任务,并给出一些上下文或模式。" M  T5 J" k- k! g+ q, H6 R' e

! }4 F  O2 ?1 r8 b6 R6 k* |completion是模型根据prompt生成的输出文本,它可以是任何文本,例如一个答案、一个续写、一个列表、一段代码等。completion的作用是尽可能地满足prompt的要求,并保持语义和逻辑的连贯性。2 ^' _# P" n+ s: N* j! \1 y" x' Q
" H& M* j4 f8 m: x7 ?5 a4 t$ O
下面是一些数据例子:6 L4 n4 b$ h0 L! l

- u+ W. i. ~( P" |{: a5 ^9 Z! O1 B3 ]/ y  ~% h
    "prompt": "对以下商品进行夸赞:彩妆中的口红品类,卖点为颜色是正红色,能提升气色 ->",
* p8 `. O1 \2 v$ ?& p/ i! r5 r    "completion": " 这口红正红色太好看了,完美提升气色,日常使用特别棒\\n"6 g) J# p3 l" ?: g
}
: N7 H# R; H, t" y: e5 K. X' M2 ?更多的例子可以看如下链接:
7 X0 d+ O/ E: E, h5 |) P8 Y
$ t7 E/ M. H8 U% T) `. d) VGPT-for-E-Commerce/test-v1.1.jsonl at b6dd9d018dce670efd28448dbd0dde0edecb3e42 · Royce17/GPT-for-E-Commerce · GitHub
3 R2 W) ]3 P: S0 _  gfinetune-with-openai/faq.jsonl at 334a69224d7e87a92de09b0d627f616be4ffa43a · A-baoYang/finetune-with-openai · GitHub
; u3 ^9 r4 C( P$ T$ u; n要微调的效果好,就要使用更多高质量的示例进行Fine-tuning,我们应该如上面链接例子一样,提供至少几百个高质量的示例,而且最好由专家审查过。6 x9 B0 m) G1 N7 i

4 C; \9 [- G3 p( p6 x& \二、在Prompt中带入知识
. b+ \) @9 s6 O* P3 b. u只需设计恰当的输入,就能让ChatGPT在上下文中生成有价值的答案,而无需修改模型的结构或参数。
3 M* W9 K! W! ]# z6 n" g3 f# _4 p6 R
输入问题时,还可以引入相关知识,使问题更加全面。这种方法的局限性在于每次输入的长度有限。5 d0 Z! y: D7 _& p
/ \4 m' L2 ?* [3 ^
下面是一些例子:
" u% b) k/ [- i& ?
. N# C2 d4 F. Y5 n- `3 G0 I1 G2 ?0 X例1:作为专业DBA,回答SQL相关问题; R" ], j& R% d% y0 a
这里在输入问题时,引入了我们的数据库表结构这个专业知识。" z1 o1 B: T7 I- N& f5 n) I4 M
+ ^( F8 s2 P- B; Y% M1 o* W
问:! s4 F, s2 ^; w/ C8 U
3 E/ O6 z1 {. x
我要你扮演一个专业DBA。我将提供给你数据表结构以及我的需求,你的目标是告知我性能最优的可执行的SQL语句,并尽可能的向我解释这段SQL语句,如果有更好的优化建议也可以提出来。- B: }5 r' x* P/ x: c, }: j

  ]6 R. B! I3 _* J( U! w" A: H+ I; u我的数据表结构为:1 @8 c* [( k8 Y) G

' r2 T1 w, P; {1 z4 U( @: oCREATE TABLE `user` (0 N# U% T+ _% ^+ {4 x2 g$ W
`id` int NOT NULL AUTO_INCREMENT,
2 f" Q" w8 |7 ~; q) c7 \`name` varchar(255) CHARACTER SET  utf8mb4 0 F! Y, Z  Z& L' J! j
      COLLATE utf8mb4_unicode_ci
3 D! d" k0 B3 @      NOT NULL DEFAULT ''
* h  e# p2 T, H: P      COMMENT '名字',, K/ j- u; Q$ t
PRIMARY KEY (`id`)
* X& s) q. D8 P+ T) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
4 {# Q% j8 B2 k; w$ R9 F      COLLATE=utf8mb4_unicode_ci 4 ?  n9 _' m) ~  G
      COMMENT='用户表';0 ~, q- O/ i" T1 b9 S
我的需求为:根据用户的名字查询用户的id2 `0 ?' h! @' u) T; A
8 G% k& u8 ^4 Y% S6 i
回答% B" B" i. ~9 e: ^) ]" p+ j
0 W3 ~' r9 R6 R+ c& v! y
好的,根据您提供的数据表结构和需求,可以使用以下SQL语句来查询用户的id:2 Y2 @" H, E. F3 Q+ K: x

9 @8 i5 Q# i5 j$ S, m8 W) sSELECT id FROM user WHERE name = '用户的名字';) }* |3 [" c5 b/ k
这条SQL语句将会在用户表中查找指定名字的用户,然后返回该用户的id。为了进一步优化查询性能,您可以在name字段上创建索引,这将会使查询更快速地匹配到所需的记录。+ b+ Z0 H; a" N9 j$ l/ }

* W. N! u5 W0 Z, |您可以使用以下SQL语句来为name字段创建索引:
. n1 ^) W. a+ S5 ]* c' G, ~6 t3 P2 Y0 T/ s% _0 q
ALTER TABLE user ADD INDEX name_index (name);
. }- k  u4 v. H- A) o& H此外,为了保证查询的效率,您需要注意以下几点:& C5 ?. G' O& P3 v$ O1 \+ l: g

" |% A& v; |+ v+ ~5 X数据表的数据量过大时,查询的速度可能会变慢。如果您的数据表中包含大量的数据,可以考虑对表进行分区或分表。
8 F. r" p% U$ ]8 O- i
$ v! t$ ?' P1 L9 T' A如果您的查询需求经常变化,您可能需要对数据库进行优化。可以通过监控数据库的性能指标,识别哪些查询最耗时,然后对其进行优化。5 h( J& T8 ^& {$ g
+ w/ a6 G3 d4 i
例2:智能客服
' B1 \1 `/ H& }" ]9 e* {3 v比如我们要做智能客服,有一些客服准则(ChatGPT做智能客服的十条服务准则 ),对于OpenAI的API来说,要注入的知识如下链接:
* @, H3 k' V5 b1 w. c2 T- v. C
# z; J! P+ s* V0 M4 z2 ~) S! Wlanying-connector/openai-xiaolan.json at master · maxim-top/lanying-connector · GitHub9 r) E1 [6 ]' p/ c+ S( W1 X

. @5 n; [' b5 n+ I) _下面代码通过消息对象的数组注入了一些上下文知识。
# D- W! r( i5 j  ^5 G8 @
. M. O: a- c: b0 o" D
6 R  R/ X  M1 X6 q( y# Note: you need to be using OpenAI Python v0.27.0 for the code below to work
. x& G" E- i+ Dimport openai
3 }/ U6 D6 c0 O/ A% u6 y
5 r8 N6 j0 e$ K9 C6 Aopenai.ChatCompletion.create(
  ]9 J: Q4 y; s6 L4 ^9 M* g  model="gpt-3.5-turbo",
( B! J0 |- X' Y, ?  messages=[
" z/ Y+ ?# G% i        {"role": "system", "content": "You are a helpful assistant."},
$ C% M* B' s% R        {"role": "user", "content": "Who won the world series in 2020?"},5 j, |. ~4 V3 z9 ]% J
        {"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
& X0 `% D4 U! ~0 X- t1 I: {& ?        {"role": "user", "content": "Where was it played?"}
. e8 [) w2 H0 U3 O) C0 v    ]+ l0 l1 J+ |- k" o4 d3 F
)
% E- r" b) T# b1 W/ x2 E" \& X! ]
2 k" c) U0 Z* L, ?$ Q! c其中0 [; m) n# V# S  m' o' U% W

2 c+ y* K# F3 P: d! f系统消息(system)有助于设置助手的行为。在上面的例子中,prompt被指示“You are a helpful assistant.”。9 l# i7 F8 ]0 X
用户消息(user)有助于指导助手。它们可以由应用程序的最终用户生成,也可以由开发人员设置为指令。在上面的例子中,用户的最后一个问题是“在哪里比赛的?” 就是通过提前设置的对话消息来帮助回答。由于模型没有过去请求的记忆,因此所有相关信息必须通过对话提供。如果对话无法满足模型的token限制,则需要以某种方式缩短。4 |& F& L  e4 |) |& p
助理消息(assistant)有助于存储之前的回复。它们也可以由开发人员编写,以帮助提供所需行为的示例。$ M$ N) R4 u0 {8 N& d! H5 T
通过上面的方式就可以完成专业领域知识的注入。
1 n) M* p" i, ^) @+ \6 {  b/ N1 `0 ~) [! E7 y
例3:通过外部链接把内容带入& g# g% K$ |- F; M. B- F3 e
下面只包含我们发起的对话部分,会话结果比较长,省略了:7 R% V2 M1 w7 ]$ V2 K

2 j. s' Q3 _/ S/ o  hUser : 您是一个金融专家,我会向您发送微软的年度报告,并在我向您发送链接后反馈给我微软10个利好和10个消极因素。你明白吗?
1 A6 ~# _8 P3 [+ h- G! h) z...6 C9 ]# c; z3 _) Q
User : Microsoft 2022 Annual Report
1 j* k$ `* D0 ?$ V8 o& A# w: {...
6 S) E, i) g2 t9 N' LUser : 我会把Nvidia最近的财报链接发给你,你能反馈我和上面微软类似的答案吗,你明白吗?1 f& U* X6 v& y7 t) k3 ~4 u
...
  S9 `) j$ n' h& X: X7 @User: NVIDIA Announces Financial Results for Fourth Quarter and Fiscal 2023 | NVIDIA Newsroom5 D+ Q* X: ]' b, w* V
...: C5 q+ u0 q2 d3 N4 g9 U
User: 您能否从Nvidia的报告中提供更多财务见解?$ C; ~/ `# Q7 ]9 X6 J
...7 n. o; ]0 g% N3 [
User: 我会把戴尔最近的财务报告的链接发给你,你能反馈我和上面微软类似的答案吗,你明白吗?
0 j( `3 p3 ^, y( W; i: K....- y3 I) Q2 h8 p. F* B+ z/ Q2 }* c
5 @  _6 n/ S# `: B2 N# L7 a
User: 比较微软、英伟达和戴尔,用表格对比下他们的资本支出、运营支出、收入、利润率和利润率百分比。( w! ~. J, m% O" t( `
...+ \' h$ ?! n4 ^" c8 o& F
User:预测下戴尔未来12个月的现金流。2 x7 v' `, G4 I8 l% r
7 u7 N: Y8 o- p0 B5 u) _. J
这种方式要确保链接可以被GPT访问到,外部链接持续稳定的可访问是必须考虑的问题。3 c% @# ^& P* L4 i# H. F

1 _. ?& j9 `; Q' }适用场景对比
) f0 K' F+ e. x( I价格对比
) k: {' ^4 W! L2 G/ N% d3 QOpenAI的相关报价看: Pricing5 l7 W5 |% Y  r2 B6 o  _0 h0 J
* S" k$ L0 ]' c. c$ J
对话类:GPT4远远高于GTP3.5。! }8 I0 j' ^  B" X
OpenAI的相关报价.png
* x- y% ~( I) [, X2 P; N/ Q( [0 B: J4 }0 B
# h/ R: b" R8 p* y  \$ P; ?
目前提供的可微调的这几个模型:Ada、Babbage、Curie、Davinci 均是原始的 GPT-3 基本模型,其中,Davinci 是最强大的模型,成本也最高,而 Curie 又比 Babbage 功能更强大(且成本更高),依此类推,这些名称是相对的。6 |/ Z* M; h6 m% K" Y, b9 d
8 V: Z6 |2 b# ?( C' p% D/ H

, L3 t2 R3 O2 x! ^3 a2 | Ada、Babbage、Curie、Davinci 均是原始的 GPT-3 基本模型.png
3 Q) K8 T# \( H9 ~1 F7 ?0 b/ c
  T, l! `; Q8 S0 X2 Q7 i. s8 H9 ?
4 q7 F. R( s3 A2 ~4 P5 X3 ?/ U
GPT3.5 和 GTP4 由于目前没有 fine-tune,所以成本就只有每次问答的成本,但由于大部分时候需要带大量的 prompts,其实隐性的成本是挺高的,我们经常可以看到一个简短的问题会带有上千个字符的 prompts。
( y7 w, V3 [( X: O8 Y7 l$ H; N2 O0 {0 r- }* c% h- x' ], ^: A4 t
而 Davinci 的 fine-tune 模型的训练成本是较高的,但一旦获得专属模型后,后续的聊天中就不再需要做预检索和背景知识的 prompts 了,可以直接进行关于该领域的知识问答。不仅 token 消耗会变小,而且速度也会更快。
& _# S5 c! x" X# n  r! ~$ @4 n3 P0 P1 b
所以目前阶段还是用在Prompt中带入知识方案比较合适,后续等对应的微调模型出来后,可以切换过去。
3 S; q3 W  s* B, c/ w! M- C5 P5 s$ s8 W( y; b+ v% U& q
长度问题0 b" S& h, v1 Q* V! V% c1 ~3 N$ F+ d1 T! {
ChatGPT的API当前是无状态的,需要自己维护会话状态和保存上下文。这可能会导致请求内容越来越大,带来高昂的费用。
( ]- m; r( f. `% N* C: X: U0 T
2 \3 I& B( k2 J+ F. P. g( p8 `但是,你可以借助OpenAI的embedding模型(https://platform.openai.com/docs ... what-are-embeddings)和本地数据库,以更智能的方式维护上下文,并且节省成本。
, J. @8 r" w5 }2 S3 e* c! m  z: o5 I7 }5 u3 ]: A
首先,将文本资料准备成易于处理的格式,并且分成小块(这是OpenAI embeddings模型的输入长度限制)。接着,利用程序调用OpenAI embedding的API将这些文本块转换成数字向量,并且将结果保存到本地数据库中。(注意,为了能够反向获得原始文本,需要将原始文本块和数字向量一起存储。)
% H: U5 p% Q) X4 k6 Z8 o& G; U( X, C7 \  P2 ~8 R( s
当需要搜索的时候,将搜索关键字转换成数字向量,并且在本地数据库中进行检索。结果集将根据匹配相似度进行打分,分越高表示越匹配。这样,可以按照匹配度倒序返回相关结果。* c; J" x* l4 o
: }9 \8 w8 Q8 l3 \
聊天场景下,当用户提问后,需要先把提问内容关键字搜索到一个相关结果集(可以本地检索,也可以通过OpenAI embedding接口获得向量后比较相似度)。然后根据拿到的结果集,将结果集加入到请求ChatGPT的prompt中。
7 ?/ K' }9 k9 m( f9 X' f5 W7 X: U/ m% L+ V# T& E
比如说用户提了一个问题:# ^( r4 ]' X# f

2 x5 _: |3 U9 i  z, ?; m6 ~! }“What's the makers's schedule?”
( }1 X2 b9 i, D5 X9 r( @* s
! l, i+ j; g% R5 ]3 @) ?+ m从数据库中检索到相关的文字段落是:
' y4 k: N4 p) t4 B; r4 U" u
1 `$ K3 |( x% K! x- h- ^% E“What I worked on...”
& q8 ?5 I5 y+ O/ ]/ J"Taste for Makers..."( B6 X* p- o% m, T

! q. J+ V$ f* w" q那么最终的prompt看起来就像这样:
5 F+ g& G, _- }
. [) ~# j* ^; |# g: d9 j4 [
6 \. G  o- K4 c" t4 v, U9 |[
2 `, W9 x5 h: a) J0 k. Q {: Y" E. s% U+ X- a# O+ t
  role: "system",
& u4 Y2 J% R% ]) z  content: "You are a helpful assistant that accurately answers queries using Paul Graham's essays. Use the text provided to form your answer, but avoid copying word-for-word from the essays. Try to use your own words when possible. Keep your answer under 5 sentences. Be accurate, helpful, concise, and clear."$ ?& @& M' O3 V7 {* Z7 Q
},  j  `5 j4 h% l4 z2 v5 j
{
3 \% n' B9 k4 I7 i" W  a, T. o* y& N role: "user",
7 I5 w- ]% @6 H3 k  o content: `Use the following passages to provide an answer
" [9 I. e8 @  r- z1 n1 }to the query: "What's the makers's schedule?"
/ Q4 w4 y: N2 `- ~& u& s2 s1. What I worked on...
! Q& S9 M" Q1 g' w) A0 [0 `, X( f" M2. Taste for Makers...`9 L" ^" W, M- Z2 \# H+ O
}
; o' r  D2 |* D9 j% ?7 `  U]$ g6 _8 O# w( `3 y) F! b

9 Z+ |8 M0 r+ Y" t" b! R9 I: a
6 z8 Z; |2 [$ z这样ChatGPT在返回结果的时候,就会加上你的数据集。
. c4 Z8 L4 M2 K" m- m0 R7 A
+ Y- O- j6 N( J. M- Q$ [, P具体实现看: GitHub - mckaywrigley/paul-graham-gpt: AI search & chat for all of Paul Graham’s essays.+ T3 g. P2 E: r) n  X6 I7 q- D6 E
) d6 V( O5 i. g% k" J3 g: h9 j0 N
总结: ~  ^4 X5 r/ C7 \
大模型的可能性真的非常多。想象一下,如果你将自己的思想和博客输入大模型,你可以训练出一个包含自己想法的模型。这个模型可以被定位为模仿人进行交流,最终创造出一个虚拟的你。对于专业领域的KOL(关键意见领袖)来说,这种方法非常有用,因为粉丝可以直接针对他的思想进行提问和交流。3 Y+ O- q. P% I/ m  v8 `
+ A6 }, r. P: u4 F8 ]0 d1 d  t  D
而对于不善写作的人来说,也可以将自己的想法以简单的问答对的形式输出,训练出一个专属机器人,再利用大模型的语言和逻辑能力来撰写包含自己思想的文章。这种方法非常值得尝试。' F6 G; y/ e. w2 N) \' M( V2 O/ a5 b
. ]  z6 X' o8 H" K7 v1 O2 x  f% D! ]  _
参考
, ?! A# y: T1 O! ?如何用 ChatGPT 构建你的专属知识问答机器人 如何用 ChatGPT 构建你的专属知识问答机器人 - Frank 的个人博客, _3 T- d3 ~; k; D
4 l$ B- e8 ?$ S- }3 V
搭建基于知识库内容的机器人 搭建基于知识库内容的机器人 | Learning Prompt0 C  |1 I0 l9 n, {* A
, }1 c$ b; @; H- E& Z: j; j
, f3 L' v3 B9 M) d0 @+ ~! V) Z
————————————————
+ a4 s+ k  A' J版权声明:本文为CSDN博主「蝈蝈俊」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。: q7 Z" n: t( N- H8 E( T8 l
原文链接:https://blog.csdn.net/ghj1976/article/details/129676157
- K# b3 J  `# a# W) H
欢迎定制:13928122889
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|通达创业无忧交流社区 ( 粤ICP备2023021749号|粤公网安备 44030402006137号 )

GMT+8, 2026-6-18 21:10 , Processed in 0.021826 second(s), 6 queries , Redis On.

Powered by Discuz! X5.0

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表