Sea*_*ude 23 python openai-api
我想将各种 PDF 中的文本发送到OpenAI 的 API。特别是针对二年级学生的 Summarize或TL;DR 摘要API。
PyMuPDF我可以使用OpenAI 提示从 PDF 中提取文本。
问题:当令牌数超过允许的 2049 时,如何最好地准备提示?
Jay*_*Jay 27
我遇到了同样的问题。这是我用来发送比 OpenAI 的 GPT3 令牌限制长得多的文本的策略。
\n根据所使用的模型(达芬奇、居里等),请求最多可以使用提示和完成之间共享的4097 个令牌。
\n如果您的提示是 4000 个令牌,那么您最多可以完成 97 个令牌。有关 OpenAI 代币以及如何计算代币的更多信息,请参阅此处。
\n为了确保我们不\xe2\x80\x99t超过提示加完成的最大长度限制,我们需要确保提示(即您的文本)和完成(即摘要)放在一起始终适合4097令牌边界。
\n因此,我们将整个文本分成多个文本块,独立地总结每个块,最后使用一个简单的" ".join()函数合并所有汇总的块。
OpenAI 对代币的数量有固定的限制。然而,令牌与单词不同。因此,我们首先需要计算可以发送到 OpenAI 的最大字数。文档说:
\n\n考虑到令牌与单词的比率,假设每个文本块有 5 个句子摘要,我们可以将大约2900 个单词发送到 OpenAI 的 GPT3。
\n我们可以从多种策略中进行选择,将整个文本分成更小的块。
\n最简单的方法是通过在空格上分割整个文本来创建所有单词的单个列表,然后创建单词桶,其中单词均匀分布在所有桶中。缺点是我们可能会中途分割一个句子并失去句子的含义,因为 GPT 最终会独立于后半部分来总结句子的前半部分 \xe2\x80\x94 忽略两者之间的任何关系大块。
\n其他选项包括分词器,例如 SentencePiece 和 spaCy\xe2\x80\x99s 句子分割器。选择后者会产生最稳定的结果。
\n以下示例分割文本 \xe2\x80\x9cMy firstbirthday wasgreat。我的 2. 甚至更好。\xe2\x80\x9d 变成两个句子的列表。
\npython -m spacy download en_core_web_sm\nRun Code Online (Sandbox Code Playgroud)\nimport spacy\nfrom spacy.lang.en import English\n\nnlp = spacy.load("en_core_web_sm")\n\ntext = "My first birthday was great. My 2. was even better."\n \nfor sentence in nlp(text).sents:\n print(sentence.text)\nRun Code Online (Sandbox Code Playgroud)\n输出
\nMy first birthday was great.\nMy 2. was even better.\nRun Code Online (Sandbox Code Playgroud)\nspaCy 正确检测到了第二个句子,而不是在 \xe2\x80\x9c2.\xe2\x80\x9d 之后将其拆分。
\n现在,让\xe2\x80\x99s 编写一个text_to_chunks辅助函数来生成句子块,其中每个块最多包含 2700 个单词。2900 个单词是最初计算的字数限制,但我们希望确保对于长度超过 1.33 个标记的单词有足够的缓冲区。
My first birthday was great.\nMy 2. was even better.\nRun Code Online (Sandbox Code Playgroud)\nOpenAI 最近推出了另一种确定文本标记数量的方法。该方法使用tiktokenOpenAI 的模型并针对其量身定制。
def text_to_chunks(text):\n chunks = [[]]\n chunk_total_words = 0\n\n sentences = nlp(text)\n\n for sentence in sentences.sents:\n chunk_total_words += len(sentence.text.split(" "))\n\n if chunk_total_words > 2700:\n chunks.append([])\n chunk_total_words = len(sentence.text.split(" "))\n\n chunks[len(chunks)-1].append(sentence.text)\n \n return chunks\nRun Code Online (Sandbox Code Playgroud)\n接下来,我们将文本摘要逻辑包装到 summarize_text 函数中。
\nimport tiktoken\n\nencoding = tiktoken.encoding_for_model("gpt-3.5-turbo")\nnumber_of_tokens = len(encoding.encode("tiktoken is great!"))\nprint(number_of_tokens)\nRun Code Online (Sandbox Code Playgroud)\n我们的最后一段代码如下所示:
\ndef summarize_text(text):\n prompt = f"Summarize the following text in 5 sentences:\\n{text}"\n\n response = openai.Completion.create(\n engine="text-davinci-003", \n prompt=prompt,\n temperature=0.3, \n max_tokens=150, # = 112 words\n top_p=1, \n frequency_penalty=0,\n presence_penalty=1\n )\n\n return response["choices"][0]["text"]\nRun Code Online (Sandbox Code Playgroud)\n