-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrate.py
99 lines (84 loc) · 3.22 KB
/
rate.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import time
import warnings
import types
import openai
import asyncio
import anthropic
import apikeys # Never commit this module, which should contain: keys={'gpt': ['keys', 'here'], 'claude': ['more', 'keys']}
model = 'gpt-4-turbo-preview'
_library = None
_claudeobj = None
_models={
'gpt': 'gpt-4-turbo-preview',
'claude': 'claude-3-5-sonnet-20240620'
}
def setkey(n : int, library='gpt'):
key = apikeys.keys[library][n]
global model, _claudeobj, _library
_library = library
model = _models[library]
if library == 'gpt':
openai.api_key = key
elif library == 'claude':
_claudeobj = anthropic.AsyncAnthropic(api_key=key)
async def entrypoint(requests, num_procs=10, **kwargs):
sem = asyncio.Semaphore(num_procs)
try:
total = len(requests)
except TypeError:
total = 'unknown'
if 'model' not in kwargs:
kwargs['model'] = model
await asyncio.gather(*(request(sem, i, total, rq, **kwargs) for i, rq in enumerate(requests)))
async def request(sem, i, total, rq, **kwargs):
async with sem:
print(f'Request {i+1} of {total}')
while kwargs:
completion = await acomplete(messages=rq['messages'], **kwargs)
if 'process' in rq:
kwargs = rq['process'](rq, completion, **kwargs)
if kwargs:
print(f'Retrying request {i+1} with params {kwargs}')
else:
rq['completion'] = completion
rq['kwargs'] = kwargs
break
async def acomplete(**kwargs):
backoff = 5 # seconds
if _library == 'gpt':
if 'system' in kwargs:
kwargs['messages'].append({'role': 'system', 'content': kwargs.pop('system')})
while True:
try:
return await openai.ChatCompletion.acreate(**kwargs)
except openai.OpenAIError as e:
print(e)
print(f'Retrying in {backoff} s...')
time.sleep(backoff) # Deliberately not awaited: Error may be rate limit.
backoff *= 2
elif _library == 'claude':
if 'messages' in kwargs and 'system' not in kwargs:
system = []
messages = []
for m in kwargs['messages']:
if m['role'] == 'system':
system.append(m['content'])
else:
messages.append(m)
kwargs['system'] = '\n'.join(system)
kwargs['messages'] = messages
if kwargs.pop('n', 1) != 1:
warnings.warn('Claude API does not support "n" parameter, ignoring (n=1).')
if 'max_tokens' not in kwargs:
kwargs['max_tokens'] = 4096
while True:
try:
response = await _claudeobj.messages.create(**kwargs)
# Patch into OpenAI format
response.choices = [types.SimpleNamespace(index=0, message=types.SimpleNamespace(role=response.role, content=response.content[0].text))]
return response
except (anthropic.RateLimitError, anthropic.InternalServerError) as e:
print(e)
print(f'Retrying in {backoff} s...')
time.sleep(backoff)
backoff *= 2