pixeltable 0.4.0rc2__py3-none-any.whl → 0.4.0rc3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pixeltable might be problematic. Click here for more details.
- pixeltable/__version__.py +2 -2
- pixeltable/functions/anthropic.py +19 -45
- pixeltable/functions/deepseek.py +19 -38
- pixeltable/functions/fireworks.py +9 -18
- pixeltable/functions/gemini.py +2 -2
- pixeltable/functions/llama_cpp.py +6 -6
- pixeltable/functions/mistralai.py +15 -41
- pixeltable/functions/ollama.py +1 -1
- pixeltable/functions/openai.py +82 -165
- pixeltable/functions/together.py +22 -80
- {pixeltable-0.4.0rc2.dist-info → pixeltable-0.4.0rc3.dist-info}/METADATA +1 -1
- {pixeltable-0.4.0rc2.dist-info → pixeltable-0.4.0rc3.dist-info}/RECORD +15 -15
- {pixeltable-0.4.0rc2.dist-info → pixeltable-0.4.0rc3.dist-info}/LICENSE +0 -0
- {pixeltable-0.4.0rc2.dist-info → pixeltable-0.4.0rc3.dist-info}/WHEEL +0 -0
- {pixeltable-0.4.0rc2.dist-info → pixeltable-0.4.0rc3.dist-info}/entry_points.txt +0 -0
pixeltable/__version__.py
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
# These version placeholders will be replaced during build.
|
|
2
|
-
__version__ = '0.4.
|
|
3
|
-
__version_tuple__ = (0, 4, "
|
|
2
|
+
__version__ = '0.4.0rc3'
|
|
3
|
+
__version_tuple__ = (0, 4, "0rc3")
|
|
@@ -8,7 +8,7 @@ the [Working with Anthropic](https://pixeltable.readme.io/docs/working-with-anth
|
|
|
8
8
|
import datetime
|
|
9
9
|
import json
|
|
10
10
|
import logging
|
|
11
|
-
from typing import TYPE_CHECKING, Any, Iterable, Optional,
|
|
11
|
+
from typing import TYPE_CHECKING, Any, Iterable, Optional, cast
|
|
12
12
|
|
|
13
13
|
import httpx
|
|
14
14
|
|
|
@@ -73,16 +73,10 @@ async def messages(
|
|
|
73
73
|
messages: list[dict[str, str]],
|
|
74
74
|
*,
|
|
75
75
|
model: str,
|
|
76
|
-
max_tokens: int
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
temperature: Optional[float] = None,
|
|
81
|
-
tool_choice: Optional[dict] = None,
|
|
82
|
-
tools: Optional[list[dict]] = None,
|
|
83
|
-
top_k: Optional[int] = None,
|
|
84
|
-
top_p: Optional[float] = None,
|
|
85
|
-
timeout: Optional[float] = None,
|
|
76
|
+
max_tokens: int,
|
|
77
|
+
model_kwargs: Optional[dict[str, Any]] = None,
|
|
78
|
+
tools: Optional[list[dict[str, Any]]] = None,
|
|
79
|
+
tool_choice: Optional[dict[str, Any]] = None,
|
|
86
80
|
) -> dict:
|
|
87
81
|
"""
|
|
88
82
|
Create a Message.
|
|
@@ -101,25 +95,27 @@ async def messages(
|
|
|
101
95
|
Args:
|
|
102
96
|
messages: Input messages.
|
|
103
97
|
model: The model that will complete your prompt.
|
|
104
|
-
|
|
105
|
-
|
|
98
|
+
model_kwargs: Additional keyword args for the Anthropic `messages` API.
|
|
99
|
+
For details on the available parameters, see: <https://docs.anthropic.com/en/api/messages>
|
|
100
|
+
tools: An optional list of Pixeltable tools to use for the request.
|
|
101
|
+
tool_choice: An optional tool choice configuration.
|
|
106
102
|
|
|
107
103
|
Returns:
|
|
108
104
|
A dictionary containing the response and other metadata.
|
|
109
105
|
|
|
110
106
|
Examples:
|
|
111
|
-
Add a computed column that applies the model `claude-3-
|
|
107
|
+
Add a computed column that applies the model `claude-3-5-sonnet-20241022`
|
|
112
108
|
to an existing Pixeltable column `tbl.prompt` of the table `tbl`:
|
|
113
109
|
|
|
114
110
|
>>> msgs = [{'role': 'user', 'content': tbl.prompt}]
|
|
115
|
-
... tbl.add_computed_column(response=messages(msgs, model='claude-3-
|
|
111
|
+
... tbl.add_computed_column(response=messages(msgs, model='claude-3-5-sonnet-20241022'))
|
|
116
112
|
"""
|
|
117
|
-
|
|
118
|
-
|
|
113
|
+
if model_kwargs is None:
|
|
114
|
+
model_kwargs = {}
|
|
119
115
|
|
|
120
116
|
if tools is not None:
|
|
121
117
|
# Reformat `tools` into Anthropic format
|
|
122
|
-
tools = [
|
|
118
|
+
model_kwargs['tools'] = [
|
|
123
119
|
{
|
|
124
120
|
'name': tool['name'],
|
|
125
121
|
'description': tool['description'],
|
|
@@ -132,17 +128,16 @@ async def messages(
|
|
|
132
128
|
for tool in tools
|
|
133
129
|
]
|
|
134
130
|
|
|
135
|
-
tool_choice_: Optional[dict] = None
|
|
136
131
|
if tool_choice is not None:
|
|
137
132
|
if tool_choice['auto']:
|
|
138
|
-
|
|
133
|
+
model_kwargs['tool_choice'] = {'type': 'auto'}
|
|
139
134
|
elif tool_choice['required']:
|
|
140
|
-
|
|
135
|
+
model_kwargs['tool_choice'] = {'type': 'any'}
|
|
141
136
|
else:
|
|
142
137
|
assert tool_choice['tool'] is not None
|
|
143
|
-
|
|
138
|
+
model_kwargs['tool_choice'] = {'type': 'tool', 'name': tool_choice['tool']}
|
|
144
139
|
if not tool_choice['parallel_tool_calls']:
|
|
145
|
-
|
|
140
|
+
model_kwargs['tool_choice']['disable_parallel_tool_use'] = True
|
|
146
141
|
|
|
147
142
|
# make sure the pool info exists prior to making the request
|
|
148
143
|
resource_pool_id = f'rate-limits:anthropic:{model}'
|
|
@@ -152,20 +147,8 @@ async def messages(
|
|
|
152
147
|
# TODO: timeouts should be set system-wide and be user-configurable
|
|
153
148
|
from anthropic.types import MessageParam
|
|
154
149
|
|
|
155
|
-
# cast(Any, ...): avoid mypy errors
|
|
156
150
|
result = await _anthropic_client().messages.with_raw_response.create(
|
|
157
|
-
messages=cast(Iterable[MessageParam], messages),
|
|
158
|
-
model=model,
|
|
159
|
-
max_tokens=max_tokens,
|
|
160
|
-
metadata=_opt(cast(Any, metadata)),
|
|
161
|
-
stop_sequences=_opt(stop_sequences),
|
|
162
|
-
system=_opt(system),
|
|
163
|
-
temperature=_opt(cast(Any, temperature)),
|
|
164
|
-
tools=_opt(cast(Any, tools)),
|
|
165
|
-
tool_choice=_opt(cast(Any, tool_choice_)),
|
|
166
|
-
top_k=_opt(top_k),
|
|
167
|
-
top_p=_opt(top_p),
|
|
168
|
-
timeout=_opt(timeout),
|
|
151
|
+
messages=cast(Iterable[MessageParam], messages), model=model, max_tokens=max_tokens, **model_kwargs
|
|
169
152
|
)
|
|
170
153
|
|
|
171
154
|
requests_limit_str = result.headers.get('anthropic-ratelimit-requests-limit')
|
|
@@ -224,15 +207,6 @@ def _anthropic_response_to_pxt_tool_calls(response: dict) -> Optional[dict]:
|
|
|
224
207
|
return pxt_tool_calls
|
|
225
208
|
|
|
226
209
|
|
|
227
|
-
_T = TypeVar('_T')
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
def _opt(arg: _T) -> Union[_T, 'anthropic.NotGiven']:
|
|
231
|
-
import anthropic
|
|
232
|
-
|
|
233
|
-
return arg if arg is not None else anthropic.NOT_GIVEN
|
|
234
|
-
|
|
235
|
-
|
|
236
210
|
__all__ = local_public_names(__name__)
|
|
237
211
|
|
|
238
212
|
|
pixeltable/functions/deepseek.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import json
|
|
2
|
-
from typing import TYPE_CHECKING, Any, Optional
|
|
2
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
3
3
|
|
|
4
4
|
import httpx
|
|
5
5
|
|
|
@@ -7,8 +7,6 @@ import pixeltable as pxt
|
|
|
7
7
|
from pixeltable import env
|
|
8
8
|
from pixeltable.utils.code import local_public_names
|
|
9
9
|
|
|
10
|
-
from .openai import _opt
|
|
11
|
-
|
|
12
10
|
if TYPE_CHECKING:
|
|
13
11
|
import openai
|
|
14
12
|
|
|
@@ -33,17 +31,9 @@ async def chat_completions(
|
|
|
33
31
|
messages: list,
|
|
34
32
|
*,
|
|
35
33
|
model: str,
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
max_tokens: Optional[int] = None,
|
|
40
|
-
presence_penalty: Optional[float] = None,
|
|
41
|
-
response_format: Optional[dict] = None,
|
|
42
|
-
stop: Optional[list[str]] = None,
|
|
43
|
-
temperature: Optional[float] = None,
|
|
44
|
-
tools: Optional[list[dict]] = None,
|
|
45
|
-
tool_choice: Optional[dict] = None,
|
|
46
|
-
top_p: Optional[float] = None,
|
|
34
|
+
model_kwargs: Optional[dict[str, Any]] = None,
|
|
35
|
+
tools: Optional[list[dict[str, Any]]] = None,
|
|
36
|
+
tool_choice: Optional[dict[str, Any]] = None,
|
|
47
37
|
) -> dict:
|
|
48
38
|
"""
|
|
49
39
|
Creates a model response for the given chat conversation.
|
|
@@ -60,8 +50,10 @@ async def chat_completions(
|
|
|
60
50
|
Args:
|
|
61
51
|
messages: A list of messages to use for chat completion, as described in the Deepseek API documentation.
|
|
62
52
|
model: The model to use for chat completion.
|
|
63
|
-
|
|
64
|
-
|
|
53
|
+
model_kwargs: Additional keyword args for the Deepseek `chat/completions` API.
|
|
54
|
+
For details on the available parameters, see: <https://api-docs.deepseek.com/api/create-chat-completion>
|
|
55
|
+
tools: An optional list of Pixeltable tools to use for the request.
|
|
56
|
+
tool_choice: An optional tool choice configuration.
|
|
65
57
|
|
|
66
58
|
Returns:
|
|
67
59
|
A dictionary containing the response and other metadata.
|
|
@@ -76,39 +68,28 @@ async def chat_completions(
|
|
|
76
68
|
]
|
|
77
69
|
tbl.add_computed_column(response=chat_completions(messages, model='deepseek-chat'))
|
|
78
70
|
"""
|
|
71
|
+
if model_kwargs is None:
|
|
72
|
+
model_kwargs = {}
|
|
73
|
+
|
|
79
74
|
if tools is not None:
|
|
80
|
-
tools = [{'type': 'function', 'function': tool} for tool in tools]
|
|
75
|
+
model_kwargs['tools'] = [{'type': 'function', 'function': tool} for tool in tools]
|
|
81
76
|
|
|
82
|
-
tool_choice_: Union[str, dict, None] = None
|
|
83
77
|
if tool_choice is not None:
|
|
84
78
|
if tool_choice['auto']:
|
|
85
|
-
|
|
79
|
+
model_kwargs['tool_choice'] = 'auto'
|
|
86
80
|
elif tool_choice['required']:
|
|
87
|
-
|
|
81
|
+
model_kwargs['tool_choice'] = 'required'
|
|
88
82
|
else:
|
|
89
83
|
assert tool_choice['tool'] is not None
|
|
90
|
-
|
|
84
|
+
model_kwargs['tool_choice'] = {'type': 'function', 'function': {'name': tool_choice['tool']}}
|
|
91
85
|
|
|
92
|
-
extra_body: Optional[dict[str, Any]] = None
|
|
93
86
|
if tool_choice is not None and not tool_choice['parallel_tool_calls']:
|
|
94
|
-
extra_body
|
|
87
|
+
if 'extra_body' not in model_kwargs:
|
|
88
|
+
model_kwargs['extra_body'] = {}
|
|
89
|
+
model_kwargs['extra_body']['parallel_tool_calls'] = False
|
|
95
90
|
|
|
96
|
-
# cast(Any, ...): avoid mypy errors
|
|
97
91
|
result = await _deepseek_client().chat.completions.with_raw_response.create(
|
|
98
|
-
messages=messages,
|
|
99
|
-
model=model,
|
|
100
|
-
frequency_penalty=_opt(frequency_penalty),
|
|
101
|
-
logprobs=_opt(logprobs),
|
|
102
|
-
top_logprobs=_opt(top_logprobs),
|
|
103
|
-
max_tokens=_opt(max_tokens),
|
|
104
|
-
presence_penalty=_opt(presence_penalty),
|
|
105
|
-
response_format=_opt(cast(Any, response_format)),
|
|
106
|
-
stop=_opt(stop),
|
|
107
|
-
temperature=_opt(temperature),
|
|
108
|
-
tools=_opt(cast(Any, tools)),
|
|
109
|
-
tool_choice=_opt(cast(Any, tool_choice_)),
|
|
110
|
-
top_p=_opt(top_p),
|
|
111
|
-
extra_body=extra_body,
|
|
92
|
+
messages=messages, model=model, **model_kwargs
|
|
112
93
|
)
|
|
113
94
|
|
|
114
95
|
return json.loads(result.text)
|
|
@@ -5,7 +5,7 @@ first `pip install fireworks-ai` and configure your Fireworks AI credentials, as
|
|
|
5
5
|
the [Working with Fireworks](https://pixeltable.readme.io/docs/working-with-fireworks) tutorial.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
from typing import TYPE_CHECKING, Optional
|
|
8
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
9
9
|
|
|
10
10
|
import pixeltable as pxt
|
|
11
11
|
from pixeltable import env
|
|
@@ -29,14 +29,7 @@ def _fireworks_client() -> 'fireworks.client.Fireworks':
|
|
|
29
29
|
|
|
30
30
|
@pxt.udf(resource_pool='request-rate:fireworks')
|
|
31
31
|
async def chat_completions(
|
|
32
|
-
messages: list[dict[str, str]],
|
|
33
|
-
*,
|
|
34
|
-
model: str,
|
|
35
|
-
max_tokens: Optional[int] = None,
|
|
36
|
-
top_k: Optional[int] = None,
|
|
37
|
-
top_p: Optional[float] = None,
|
|
38
|
-
temperature: Optional[float] = None,
|
|
39
|
-
request_timeout: Optional[int] = None,
|
|
32
|
+
messages: list[dict[str, str]], *, model: str, model_kwargs: Optional[dict[str, Any]] = None
|
|
40
33
|
) -> dict:
|
|
41
34
|
"""
|
|
42
35
|
Creates a model response for the given chat conversation.
|
|
@@ -55,8 +48,8 @@ async def chat_completions(
|
|
|
55
48
|
Args:
|
|
56
49
|
messages: A list of messages comprising the conversation so far.
|
|
57
50
|
model: The name of the model to use.
|
|
58
|
-
|
|
59
|
-
|
|
51
|
+
model_kwargs: Additional keyword args for the Fireworks `chat_completions` API. For details on the available
|
|
52
|
+
parameters, see: <https://docs.fireworks.ai/api-reference/post-chatcompletions>
|
|
60
53
|
|
|
61
54
|
Returns:
|
|
62
55
|
A dictionary containing the response and other metadata.
|
|
@@ -70,20 +63,18 @@ async def chat_completions(
|
|
|
70
63
|
... response=chat_completions(messages, model='accounts/fireworks/models/mixtral-8x22b-instruct')
|
|
71
64
|
... )
|
|
72
65
|
"""
|
|
73
|
-
|
|
74
|
-
|
|
66
|
+
if model_kwargs is None:
|
|
67
|
+
model_kwargs = {}
|
|
75
68
|
|
|
76
69
|
# for debugging purposes:
|
|
77
70
|
# res_sync = _fireworks_client().chat.completions.create(model=model, messages=messages, **kwargs_not_none)
|
|
78
71
|
# res_sync_dict = res_sync.dict()
|
|
79
72
|
|
|
80
|
-
if request_timeout
|
|
81
|
-
request_timeout = Config.get().get_int_value('timeout', section='fireworks') or 600
|
|
73
|
+
if 'request_timeout' not in model_kwargs:
|
|
74
|
+
model_kwargs['request_timeout'] = Config.get().get_int_value('timeout', section='fireworks') or 600
|
|
82
75
|
# TODO: this timeout doesn't really work, I think it only applies to returning the stream, but not to the timing
|
|
83
76
|
# of the chunks; addressing this would require a timeout for the task running this udf
|
|
84
|
-
stream = _fireworks_client().chat.completions.acreate(
|
|
85
|
-
model=model, messages=messages, request_timeout=request_timeout, **kwargs_not_none
|
|
86
|
-
)
|
|
77
|
+
stream = _fireworks_client().chat.completions.acreate(model=model, messages=messages, **model_kwargs)
|
|
87
78
|
chunks = []
|
|
88
79
|
async for chunk in stream:
|
|
89
80
|
chunks.append(chunk)
|
pixeltable/functions/gemini.py
CHANGED
|
@@ -53,8 +53,8 @@ async def generate_content(
|
|
|
53
53
|
config: Configuration for generation, corresponding to keyword arguments of
|
|
54
54
|
`genai.types.GenerateContentConfig`. For details on the parameters, see:
|
|
55
55
|
<https://googleapis.github.io/python-genai/genai.html#module-genai.types>
|
|
56
|
-
tools:
|
|
57
|
-
`config
|
|
56
|
+
tools: An optional list of Pixeltable tools to use. It is also possible to specify tools manually via the
|
|
57
|
+
`config['tools']` parameter, but at most one of `config['tools']` or `tools` may be used.
|
|
58
58
|
|
|
59
59
|
Returns:
|
|
60
60
|
A dictionary containing the response and other metadata.
|
|
@@ -17,7 +17,7 @@ def create_chat_completion(
|
|
|
17
17
|
model_path: Optional[str] = None,
|
|
18
18
|
repo_id: Optional[str] = None,
|
|
19
19
|
repo_filename: Optional[str] = None,
|
|
20
|
-
|
|
20
|
+
model_kwargs: Optional[dict[str, Any]] = None,
|
|
21
21
|
) -> dict:
|
|
22
22
|
"""
|
|
23
23
|
Generate a chat completion from a list of messages.
|
|
@@ -35,14 +35,14 @@ def create_chat_completion(
|
|
|
35
35
|
repo_id: The Hugging Face model repo id (if using a pretrained model).
|
|
36
36
|
repo_filename: A filename or glob pattern to match the model file in the repo (optional, if using a
|
|
37
37
|
pretrained model).
|
|
38
|
-
|
|
39
|
-
`top_p`, and `top_k`. For details, see the
|
|
38
|
+
model_kwargs: Additional keyword args for the llama_cpp `create_chat_completions` API, such as `max_tokens`,
|
|
39
|
+
`temperature`, `top_p`, and `top_k`. For details, see the
|
|
40
40
|
[llama_cpp create_chat_completions documentation](https://llama-cpp-python.readthedocs.io/en/latest/api-reference/#llama_cpp.Llama.create_chat_completion).
|
|
41
41
|
"""
|
|
42
42
|
Env.get().require_package('llama_cpp', min_version=[0, 3, 1])
|
|
43
43
|
|
|
44
|
-
if
|
|
45
|
-
|
|
44
|
+
if model_kwargs is None:
|
|
45
|
+
model_kwargs = {}
|
|
46
46
|
|
|
47
47
|
if (model_path is None) == (repo_id is None):
|
|
48
48
|
raise excs.Error('Exactly one of `model_path` or `repo_id` must be provided.')
|
|
@@ -56,7 +56,7 @@ def create_chat_completion(
|
|
|
56
56
|
else:
|
|
57
57
|
Env.get().require_package('huggingface_hub')
|
|
58
58
|
llm = _lookup_pretrained_model(repo_id, repo_filename, n_gpu_layers)
|
|
59
|
-
return llm.create_chat_completion(messages, **
|
|
59
|
+
return llm.create_chat_completion(messages, **model_kwargs) # type: ignore
|
|
60
60
|
|
|
61
61
|
|
|
62
62
|
def _is_gpu_available() -> bool:
|
|
@@ -5,7 +5,7 @@ first `pip install mistralai` and configure your Mistral AI credentials, as desc
|
|
|
5
5
|
the [Working with Mistral AI](https://pixeltable.readme.io/docs/working-with-mistralai) tutorial.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
from typing import TYPE_CHECKING, Optional, TypeVar, Union
|
|
8
|
+
from typing import TYPE_CHECKING, Any, Optional, TypeVar, Union
|
|
9
9
|
|
|
10
10
|
import numpy as np
|
|
11
11
|
|
|
@@ -32,16 +32,7 @@ def _mistralai_client() -> 'mistralai.Mistral':
|
|
|
32
32
|
|
|
33
33
|
@pxt.udf(resource_pool='request-rate:mistral')
|
|
34
34
|
async def chat_completions(
|
|
35
|
-
messages: list[dict[str, str]],
|
|
36
|
-
*,
|
|
37
|
-
model: str,
|
|
38
|
-
temperature: Optional[float] = 0.7,
|
|
39
|
-
top_p: Optional[float] = 1.0,
|
|
40
|
-
max_tokens: Optional[int] = None,
|
|
41
|
-
stop: Optional[list[str]] = None,
|
|
42
|
-
random_seed: Optional[int] = None,
|
|
43
|
-
response_format: Optional[dict] = None,
|
|
44
|
-
safe_prompt: Optional[bool] = False,
|
|
35
|
+
messages: list[dict[str, str]], *, model: str, model_kwargs: Optional[dict[str, Any]] = None
|
|
45
36
|
) -> dict:
|
|
46
37
|
"""
|
|
47
38
|
Chat Completion API.
|
|
@@ -60,6 +51,8 @@ async def chat_completions(
|
|
|
60
51
|
Args:
|
|
61
52
|
messages: The prompt(s) to generate completions for.
|
|
62
53
|
model: ID of the model to use. (See overview here: <https://docs.mistral.ai/getting-started/models/>)
|
|
54
|
+
model_kwargs: Additional keyword args for the Mistral `chat/completions` API.
|
|
55
|
+
For details on the available parameters, see: <https://docs.mistral.ai/api/#tag/chat>
|
|
63
56
|
|
|
64
57
|
For details on the other parameters, see: <https://docs.mistral.ai/api/#tag/chat>
|
|
65
58
|
|
|
@@ -73,34 +66,20 @@ async def chat_completions(
|
|
|
73
66
|
>>> messages = [{'role': 'user', 'content': tbl.prompt}]
|
|
74
67
|
... tbl.add_computed_column(response=completions(messages, model='mistral-latest-small'))
|
|
75
68
|
"""
|
|
69
|
+
if model_kwargs is None:
|
|
70
|
+
model_kwargs = {}
|
|
71
|
+
|
|
76
72
|
Env.get().require_package('mistralai')
|
|
77
73
|
result = await _mistralai_client().chat.complete_async(
|
|
78
74
|
messages=messages, # type: ignore[arg-type]
|
|
79
75
|
model=model,
|
|
80
|
-
|
|
81
|
-
top_p=top_p,
|
|
82
|
-
max_tokens=_opt(max_tokens),
|
|
83
|
-
stop=stop,
|
|
84
|
-
random_seed=_opt(random_seed),
|
|
85
|
-
response_format=response_format, # type: ignore[arg-type]
|
|
86
|
-
safe_prompt=safe_prompt,
|
|
76
|
+
**model_kwargs,
|
|
87
77
|
)
|
|
88
78
|
return result.dict()
|
|
89
79
|
|
|
90
80
|
|
|
91
81
|
@pxt.udf(resource_pool='request-rate:mistral')
|
|
92
|
-
async def fim_completions(
|
|
93
|
-
prompt: str,
|
|
94
|
-
*,
|
|
95
|
-
model: str,
|
|
96
|
-
temperature: Optional[float] = 0.7,
|
|
97
|
-
top_p: Optional[float] = 1.0,
|
|
98
|
-
max_tokens: Optional[int] = None,
|
|
99
|
-
min_tokens: Optional[int] = None,
|
|
100
|
-
stop: Optional[list[str]] = None,
|
|
101
|
-
random_seed: Optional[int] = None,
|
|
102
|
-
suffix: Optional[str] = None,
|
|
103
|
-
) -> dict:
|
|
82
|
+
async def fim_completions(prompt: str, *, model: str, model_kwargs: Optional[dict[str, Any]] = None) -> dict:
|
|
104
83
|
"""
|
|
105
84
|
Fill-in-the-middle Completion API.
|
|
106
85
|
|
|
@@ -118,6 +97,8 @@ async def fim_completions(
|
|
|
118
97
|
Args:
|
|
119
98
|
prompt: The text/code to complete.
|
|
120
99
|
model: ID of the model to use. (See overview here: <https://docs.mistral.ai/getting-started/models/>)
|
|
100
|
+
model_kwargs: Additional keyword args for the Mistral `fim/completions` API.
|
|
101
|
+
For details on the available parameters, see: <https://docs.mistral.ai/api/#tag/fim>
|
|
121
102
|
|
|
122
103
|
For details on the other parameters, see: <https://docs.mistral.ai/api/#tag/fim>
|
|
123
104
|
|
|
@@ -130,18 +111,11 @@ async def fim_completions(
|
|
|
130
111
|
|
|
131
112
|
>>> tbl.add_computed_column(response=completions(tbl.prompt, model='codestral-latest'))
|
|
132
113
|
"""
|
|
114
|
+
if model_kwargs is None:
|
|
115
|
+
model_kwargs = {}
|
|
116
|
+
|
|
133
117
|
Env.get().require_package('mistralai')
|
|
134
|
-
result = await _mistralai_client().fim.complete_async(
|
|
135
|
-
prompt=prompt,
|
|
136
|
-
model=model,
|
|
137
|
-
temperature=temperature,
|
|
138
|
-
top_p=top_p,
|
|
139
|
-
max_tokens=_opt(max_tokens),
|
|
140
|
-
min_tokens=_opt(min_tokens),
|
|
141
|
-
stop=stop,
|
|
142
|
-
random_seed=_opt(random_seed),
|
|
143
|
-
suffix=_opt(suffix),
|
|
144
|
-
)
|
|
118
|
+
result = await _mistralai_client().fim.complete_async(prompt=prompt, model=model, **model_kwargs)
|
|
145
119
|
return result.dict()
|
|
146
120
|
|
|
147
121
|
|
pixeltable/functions/ollama.py
CHANGED
|
@@ -50,7 +50,7 @@ def generate(
|
|
|
50
50
|
template: Prompt template to use.
|
|
51
51
|
context: The context parameter returned from a previous call to `generate()`.
|
|
52
52
|
raw: If `True`, no formatting will be applied to the prompt.
|
|
53
|
-
options: Additional options
|
|
53
|
+
options: Additional options for the Ollama `chat` call, such as `max_tokens`, `temperature`, `top_p`, and
|
|
54
54
|
`top_k`. For details, see the
|
|
55
55
|
[Valid Parameters and Values](https://github.com/ollama/ollama/blob/main/docs/modelfile.md#valid-parameters-and-values)
|
|
56
56
|
section of the Ollama documentation.
|
pixeltable/functions/openai.py
CHANGED
|
@@ -14,15 +14,14 @@ import math
|
|
|
14
14
|
import pathlib
|
|
15
15
|
import re
|
|
16
16
|
import uuid
|
|
17
|
-
from typing import TYPE_CHECKING, Any, Callable,
|
|
17
|
+
from typing import TYPE_CHECKING, Any, Callable, Optional, Type
|
|
18
18
|
|
|
19
19
|
import httpx
|
|
20
20
|
import numpy as np
|
|
21
21
|
import PIL
|
|
22
22
|
|
|
23
23
|
import pixeltable as pxt
|
|
24
|
-
import
|
|
25
|
-
from pixeltable import env, exprs
|
|
24
|
+
from pixeltable import env, exprs, type_system as ts
|
|
26
25
|
from pixeltable.func import Batch, Tools
|
|
27
26
|
from pixeltable.utils.code import local_public_names
|
|
28
27
|
|
|
@@ -171,15 +170,7 @@ def _get_header_info(
|
|
|
171
170
|
|
|
172
171
|
|
|
173
172
|
@pxt.udf
|
|
174
|
-
async def speech(
|
|
175
|
-
input: str,
|
|
176
|
-
*,
|
|
177
|
-
model: str,
|
|
178
|
-
voice: str,
|
|
179
|
-
response_format: Optional[str] = None,
|
|
180
|
-
speed: Optional[float] = None,
|
|
181
|
-
timeout: Optional[float] = None,
|
|
182
|
-
) -> pxt.Audio:
|
|
173
|
+
async def speech(input: str, *, model: str, voice: str, model_kwargs: Optional[dict[str, Any]] = None) -> pxt.Audio:
|
|
183
174
|
"""
|
|
184
175
|
Generates audio from the input text.
|
|
185
176
|
|
|
@@ -199,8 +190,8 @@ async def speech(
|
|
|
199
190
|
model: The model to use for speech synthesis.
|
|
200
191
|
voice: The voice profile to use for speech synthesis. Supported options include:
|
|
201
192
|
`alloy`, `echo`, `fable`, `onyx`, `nova`, and `shimmer`.
|
|
202
|
-
|
|
203
|
-
|
|
193
|
+
model_kwargs: Additional keyword args for the OpenAI `audio/speech` API. For details on the available
|
|
194
|
+
parameters, see: <https://platform.openai.com/docs/api-reference/audio/createSpeech>
|
|
204
195
|
|
|
205
196
|
Returns:
|
|
206
197
|
An audio file containing the synthesized speech.
|
|
@@ -211,30 +202,23 @@ async def speech(
|
|
|
211
202
|
|
|
212
203
|
>>> tbl.add_computed_column(audio=speech(tbl.text, model='tts-1', voice='nova'))
|
|
213
204
|
"""
|
|
205
|
+
if model_kwargs is None:
|
|
206
|
+
model_kwargs = {}
|
|
207
|
+
|
|
214
208
|
content = await _openai_client().audio.speech.create(
|
|
215
209
|
input=input,
|
|
216
210
|
model=model,
|
|
217
211
|
voice=voice, # type: ignore
|
|
218
|
-
|
|
219
|
-
speed=_opt(speed),
|
|
220
|
-
timeout=_opt(timeout),
|
|
212
|
+
**model_kwargs,
|
|
221
213
|
)
|
|
222
|
-
ext = response_format
|
|
214
|
+
ext = model_kwargs.get('response_format', 'mp3')
|
|
223
215
|
output_filename = str(env.Env.get().tmp_dir / f'{uuid.uuid4()}.{ext}')
|
|
224
216
|
content.write_to_file(output_filename)
|
|
225
217
|
return output_filename
|
|
226
218
|
|
|
227
219
|
|
|
228
220
|
@pxt.udf
|
|
229
|
-
async def transcriptions(
|
|
230
|
-
audio: pxt.Audio,
|
|
231
|
-
*,
|
|
232
|
-
model: str,
|
|
233
|
-
language: Optional[str] = None,
|
|
234
|
-
prompt: Optional[str] = None,
|
|
235
|
-
temperature: Optional[float] = None,
|
|
236
|
-
timeout: Optional[float] = None,
|
|
237
|
-
) -> dict:
|
|
221
|
+
async def transcriptions(audio: pxt.Audio, *, model: str, model_kwargs: Optional[dict[str, Any]] = None) -> dict:
|
|
238
222
|
"""
|
|
239
223
|
Transcribes audio into the input language.
|
|
240
224
|
|
|
@@ -252,8 +236,8 @@ async def transcriptions(
|
|
|
252
236
|
Args:
|
|
253
237
|
audio: The audio to transcribe.
|
|
254
238
|
model: The model to use for speech transcription.
|
|
255
|
-
|
|
256
|
-
|
|
239
|
+
model_kwargs: Additional keyword args for the OpenAI `audio/transcriptions` API. For details on the available
|
|
240
|
+
parameters, see: <https://platform.openai.com/docs/api-reference/audio/createTranscription>
|
|
257
241
|
|
|
258
242
|
Returns:
|
|
259
243
|
A dictionary containing the transcription and other metadata.
|
|
@@ -264,27 +248,16 @@ async def transcriptions(
|
|
|
264
248
|
|
|
265
249
|
>>> tbl.add_computed_column(transcription=transcriptions(tbl.audio, model='whisper-1', language='en'))
|
|
266
250
|
"""
|
|
251
|
+
if model_kwargs is None:
|
|
252
|
+
model_kwargs = {}
|
|
253
|
+
|
|
267
254
|
file = pathlib.Path(audio)
|
|
268
|
-
transcription = await _openai_client().audio.transcriptions.create(
|
|
269
|
-
file=file,
|
|
270
|
-
model=model,
|
|
271
|
-
language=_opt(language),
|
|
272
|
-
prompt=_opt(prompt),
|
|
273
|
-
temperature=_opt(temperature),
|
|
274
|
-
timeout=_opt(timeout),
|
|
275
|
-
)
|
|
255
|
+
transcription = await _openai_client().audio.transcriptions.create(file=file, model=model, **model_kwargs)
|
|
276
256
|
return transcription.dict()
|
|
277
257
|
|
|
278
258
|
|
|
279
259
|
@pxt.udf
|
|
280
|
-
async def translations(
|
|
281
|
-
audio: pxt.Audio,
|
|
282
|
-
*,
|
|
283
|
-
model: str,
|
|
284
|
-
prompt: Optional[str] = None,
|
|
285
|
-
temperature: Optional[float] = None,
|
|
286
|
-
timeout: Optional[float] = None,
|
|
287
|
-
) -> dict:
|
|
260
|
+
async def translations(audio: pxt.Audio, *, model: str, model_kwargs: Optional[dict[str, Any]] = None) -> dict:
|
|
288
261
|
"""
|
|
289
262
|
Translates audio into English.
|
|
290
263
|
|
|
@@ -302,8 +275,8 @@ async def translations(
|
|
|
302
275
|
Args:
|
|
303
276
|
audio: The audio to translate.
|
|
304
277
|
model: The model to use for speech transcription and translation.
|
|
305
|
-
|
|
306
|
-
|
|
278
|
+
model_kwargs: Additional keyword args for the OpenAI `audio/translations` API. For details on the available
|
|
279
|
+
parameters, see: <https://platform.openai.com/docs/api-reference/audio/createTranslation>
|
|
307
280
|
|
|
308
281
|
Returns:
|
|
309
282
|
A dictionary containing the translation and other metadata.
|
|
@@ -314,10 +287,11 @@ async def translations(
|
|
|
314
287
|
|
|
315
288
|
>>> tbl.add_computed_column(translation=translations(tbl.audio, model='whisper-1', language='en'))
|
|
316
289
|
"""
|
|
290
|
+
if model_kwargs is None:
|
|
291
|
+
model_kwargs = {}
|
|
292
|
+
|
|
317
293
|
file = pathlib.Path(audio)
|
|
318
|
-
translation = await _openai_client().audio.translations.create(
|
|
319
|
-
file=file, model=model, prompt=_opt(prompt), temperature=_opt(temperature), timeout=_opt(timeout)
|
|
320
|
-
)
|
|
294
|
+
translation = await _openai_client().audio.translations.create(file=file, model=model, **model_kwargs)
|
|
321
295
|
return translation.dict()
|
|
322
296
|
|
|
323
297
|
|
|
@@ -353,8 +327,15 @@ def _is_model_family(model: str, family: str) -> bool:
|
|
|
353
327
|
|
|
354
328
|
|
|
355
329
|
def _chat_completions_get_request_resources(
|
|
356
|
-
messages: list, model: str,
|
|
330
|
+
messages: list, model: str, model_kwargs: Optional[dict[str, Any]]
|
|
357
331
|
) -> dict[str, int]:
|
|
332
|
+
if model_kwargs is None:
|
|
333
|
+
model_kwargs = {}
|
|
334
|
+
|
|
335
|
+
max_completion_tokens = model_kwargs.get('max_completion_tokens')
|
|
336
|
+
max_tokens = model_kwargs.get('max_tokens')
|
|
337
|
+
n = model_kwargs.get('n')
|
|
338
|
+
|
|
358
339
|
completion_tokens = (n or 1) * (max_completion_tokens or max_tokens or _default_max_tokens(model))
|
|
359
340
|
|
|
360
341
|
num_tokens = 0.0
|
|
@@ -373,24 +354,9 @@ async def chat_completions(
|
|
|
373
354
|
messages: list,
|
|
374
355
|
*,
|
|
375
356
|
model: str,
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
top_logprobs: Optional[int] = None,
|
|
380
|
-
max_completion_tokens: Optional[int] = None,
|
|
381
|
-
max_tokens: Optional[int] = None,
|
|
382
|
-
n: Optional[int] = None,
|
|
383
|
-
presence_penalty: Optional[float] = None,
|
|
384
|
-
reasoning_effort: Optional[Literal['low', 'medium', 'high']] = None,
|
|
385
|
-
response_format: Optional[dict] = None,
|
|
386
|
-
seed: Optional[int] = None,
|
|
387
|
-
stop: Optional[list[str]] = None,
|
|
388
|
-
temperature: Optional[float] = None,
|
|
389
|
-
tools: Optional[list[dict]] = None,
|
|
390
|
-
tool_choice: Optional[dict] = None,
|
|
391
|
-
top_p: Optional[float] = None,
|
|
392
|
-
user: Optional[str] = None,
|
|
393
|
-
timeout: Optional[float] = None,
|
|
357
|
+
model_kwargs: Optional[dict[str, Any]] = None,
|
|
358
|
+
tools: Optional[list[dict[str, Any]]] = None,
|
|
359
|
+
tool_choice: Optional[dict[str, Any]] = None,
|
|
394
360
|
) -> dict:
|
|
395
361
|
"""
|
|
396
362
|
Creates a model response for the given chat conversation.
|
|
@@ -409,8 +375,8 @@ async def chat_completions(
|
|
|
409
375
|
Args:
|
|
410
376
|
messages: A list of messages to use for chat completion, as described in the OpenAI API documentation.
|
|
411
377
|
model: The model to use for chat completion.
|
|
412
|
-
|
|
413
|
-
|
|
378
|
+
model_kwargs: Additional keyword args for the OpenAI `chat/completions` API. For details on the available
|
|
379
|
+
parameters, see: <https://platform.openai.com/docs/api-reference/chat/create>
|
|
414
380
|
|
|
415
381
|
Returns:
|
|
416
382
|
A dictionary containing the response and other metadata.
|
|
@@ -425,22 +391,23 @@ async def chat_completions(
|
|
|
425
391
|
]
|
|
426
392
|
tbl.add_computed_column(response=chat_completions(messages, model='gpt-4o-mini'))
|
|
427
393
|
"""
|
|
394
|
+
if model_kwargs is None:
|
|
395
|
+
model_kwargs = {}
|
|
396
|
+
|
|
428
397
|
if tools is not None:
|
|
429
|
-
tools = [{'type': 'function', 'function': tool} for tool in tools]
|
|
398
|
+
model_kwargs['tools'] = [{'type': 'function', 'function': tool} for tool in tools]
|
|
430
399
|
|
|
431
|
-
tool_choice_: Union[str, dict, None] = None
|
|
432
400
|
if tool_choice is not None:
|
|
433
401
|
if tool_choice['auto']:
|
|
434
|
-
|
|
402
|
+
model_kwargs['tool_choice'] = 'auto'
|
|
435
403
|
elif tool_choice['required']:
|
|
436
|
-
|
|
404
|
+
model_kwargs['tool_choice'] = 'required'
|
|
437
405
|
else:
|
|
438
406
|
assert tool_choice['tool'] is not None
|
|
439
|
-
|
|
407
|
+
model_kwargs['tool_choice'] = {'type': 'function', 'function': {'name': tool_choice['tool']}}
|
|
440
408
|
|
|
441
|
-
extra_body: Optional[dict[str, Any]] = None
|
|
442
409
|
if tool_choice is not None and not tool_choice['parallel_tool_calls']:
|
|
443
|
-
|
|
410
|
+
model_kwargs['parallel_tool_calls'] = False
|
|
444
411
|
|
|
445
412
|
# make sure the pool info exists prior to making the request
|
|
446
413
|
resource_pool = _rate_limits_pool(model)
|
|
@@ -448,29 +415,8 @@ async def chat_completions(
|
|
|
448
415
|
resource_pool, lambda: OpenAIRateLimitsInfo(_chat_completions_get_request_resources)
|
|
449
416
|
)
|
|
450
417
|
|
|
451
|
-
# cast(Any, ...): avoid mypy errors
|
|
452
418
|
result = await _openai_client().chat.completions.with_raw_response.create(
|
|
453
|
-
messages=messages,
|
|
454
|
-
model=model,
|
|
455
|
-
frequency_penalty=_opt(frequency_penalty),
|
|
456
|
-
logit_bias=_opt(logit_bias),
|
|
457
|
-
logprobs=_opt(logprobs),
|
|
458
|
-
top_logprobs=_opt(top_logprobs),
|
|
459
|
-
max_completion_tokens=_opt(max_completion_tokens),
|
|
460
|
-
max_tokens=_opt(max_tokens),
|
|
461
|
-
n=_opt(n),
|
|
462
|
-
presence_penalty=_opt(presence_penalty),
|
|
463
|
-
reasoning_effort=_opt(reasoning_effort),
|
|
464
|
-
response_format=_opt(cast(Any, response_format)),
|
|
465
|
-
seed=_opt(seed),
|
|
466
|
-
stop=_opt(stop),
|
|
467
|
-
temperature=_opt(temperature),
|
|
468
|
-
tools=_opt(cast(Any, tools)),
|
|
469
|
-
tool_choice=_opt(cast(Any, tool_choice_)),
|
|
470
|
-
top_p=_opt(top_p),
|
|
471
|
-
user=_opt(user),
|
|
472
|
-
timeout=_opt(timeout),
|
|
473
|
-
extra_body=extra_body,
|
|
419
|
+
messages=messages, model=model, **model_kwargs
|
|
474
420
|
)
|
|
475
421
|
|
|
476
422
|
requests_info, tokens_info = _get_header_info(result.headers)
|
|
@@ -480,13 +426,15 @@ async def chat_completions(
|
|
|
480
426
|
|
|
481
427
|
|
|
482
428
|
def _vision_get_request_resources(
|
|
483
|
-
prompt: str,
|
|
484
|
-
image: PIL.Image.Image,
|
|
485
|
-
model: str,
|
|
486
|
-
max_completion_tokens: Optional[int],
|
|
487
|
-
max_tokens: Optional[int],
|
|
488
|
-
n: Optional[int],
|
|
429
|
+
prompt: str, image: PIL.Image.Image, model: str, model_kwargs: Optional[dict[str, Any]] = None
|
|
489
430
|
) -> dict[str, int]:
|
|
431
|
+
if model_kwargs is None:
|
|
432
|
+
model_kwargs = {}
|
|
433
|
+
|
|
434
|
+
max_completion_tokens = model_kwargs.get('max_completion_tokens')
|
|
435
|
+
max_tokens = model_kwargs.get('max_tokens')
|
|
436
|
+
n = model_kwargs.get('n')
|
|
437
|
+
|
|
490
438
|
completion_tokens = (n or 1) * (max_completion_tokens or max_tokens or _default_max_tokens(model))
|
|
491
439
|
prompt_tokens = len(prompt) / 4
|
|
492
440
|
|
|
@@ -515,14 +463,7 @@ def _vision_get_request_resources(
|
|
|
515
463
|
|
|
516
464
|
@pxt.udf
|
|
517
465
|
async def vision(
|
|
518
|
-
prompt: str,
|
|
519
|
-
image: PIL.Image.Image,
|
|
520
|
-
*,
|
|
521
|
-
model: str,
|
|
522
|
-
max_completion_tokens: Optional[int] = None,
|
|
523
|
-
max_tokens: Optional[int] = None,
|
|
524
|
-
n: Optional[int] = 1,
|
|
525
|
-
timeout: Optional[float] = None,
|
|
466
|
+
prompt: str, image: PIL.Image.Image, *, model: str, model_kwargs: Optional[dict[str, Any]] = None
|
|
526
467
|
) -> str:
|
|
527
468
|
"""
|
|
528
469
|
Analyzes an image with the OpenAI vision capability. This is a convenience function that takes an image and
|
|
@@ -552,6 +493,9 @@ async def vision(
|
|
|
552
493
|
|
|
553
494
|
>>> tbl.add_computed_column(response=vision("What's in this image?", tbl.image, model='gpt-4o-mini'))
|
|
554
495
|
"""
|
|
496
|
+
if model_kwargs is None:
|
|
497
|
+
model_kwargs = {}
|
|
498
|
+
|
|
555
499
|
# TODO(aaron-siegel): Decompose CPU/GPU ops into separate functions
|
|
556
500
|
bytes_arr = io.BytesIO()
|
|
557
501
|
image.save(bytes_arr, format='png')
|
|
@@ -576,10 +520,7 @@ async def vision(
|
|
|
576
520
|
result = await _openai_client().chat.completions.with_raw_response.create(
|
|
577
521
|
messages=messages, # type: ignore
|
|
578
522
|
model=model,
|
|
579
|
-
|
|
580
|
-
max_tokens=_opt(max_tokens),
|
|
581
|
-
n=_opt(n),
|
|
582
|
-
timeout=_opt(timeout),
|
|
523
|
+
**model_kwargs,
|
|
583
524
|
)
|
|
584
525
|
|
|
585
526
|
requests_info, tokens_info = _get_header_info(result.headers)
|
|
@@ -606,12 +547,7 @@ def _embeddings_get_request_resources(input: list[str]) -> dict[str, int]:
|
|
|
606
547
|
|
|
607
548
|
@pxt.udf(batch_size=32)
|
|
608
549
|
async def embeddings(
|
|
609
|
-
input: Batch[str],
|
|
610
|
-
*,
|
|
611
|
-
model: str,
|
|
612
|
-
dimensions: Optional[int] = None,
|
|
613
|
-
user: Optional[str] = None,
|
|
614
|
-
timeout: Optional[float] = None,
|
|
550
|
+
input: Batch[str], *, model: str, model_kwargs: Optional[dict[str, Any]] = None
|
|
615
551
|
) -> Batch[pxt.Array[(None,), pxt.Float]]:
|
|
616
552
|
"""
|
|
617
553
|
Creates an embedding vector representing the input text.
|
|
@@ -630,10 +566,8 @@ async def embeddings(
|
|
|
630
566
|
Args:
|
|
631
567
|
input: The text to embed.
|
|
632
568
|
model: The model to use for the embedding.
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
For details on the other parameters, see: <https://platform.openai.com/docs/api-reference/embeddings>
|
|
569
|
+
model_kwargs: Additional keyword args for the OpenAI `embeddings` API. For details on the available
|
|
570
|
+
parameters, see: <https://platform.openai.com/docs/api-reference/embeddings>
|
|
637
571
|
|
|
638
572
|
Returns:
|
|
639
573
|
An array representing the application of the given embedding to `input`.
|
|
@@ -648,18 +582,16 @@ async def embeddings(
|
|
|
648
582
|
|
|
649
583
|
>>> tbl.add_embedding_index(embedding=embeddings.using(model='text-embedding-3-small'))
|
|
650
584
|
"""
|
|
585
|
+
if model_kwargs is None:
|
|
586
|
+
model_kwargs = {}
|
|
587
|
+
|
|
651
588
|
_logger.debug(f'embeddings: batch_size={len(input)}')
|
|
652
589
|
resource_pool = _rate_limits_pool(model)
|
|
653
590
|
rate_limits_info = env.Env.get().get_resource_pool_info(
|
|
654
591
|
resource_pool, lambda: OpenAIRateLimitsInfo(_embeddings_get_request_resources)
|
|
655
592
|
)
|
|
656
593
|
result = await _openai_client().embeddings.with_raw_response.create(
|
|
657
|
-
input=input,
|
|
658
|
-
model=model,
|
|
659
|
-
dimensions=_opt(dimensions),
|
|
660
|
-
user=_opt(user),
|
|
661
|
-
encoding_format='float',
|
|
662
|
-
timeout=_opt(timeout),
|
|
594
|
+
input=input, model=model, encoding_format='float', **model_kwargs
|
|
663
595
|
)
|
|
664
596
|
requests_info, tokens_info = _get_header_info(result.headers)
|
|
665
597
|
rate_limits_info.record(requests=requests_info, tokens=tokens_info)
|
|
@@ -667,7 +599,10 @@ async def embeddings(
|
|
|
667
599
|
|
|
668
600
|
|
|
669
601
|
@embeddings.conditional_return_type
|
|
670
|
-
def _(model: str,
|
|
602
|
+
def _(model: str, model_kwargs: Optional[dict[str, Any]] = None) -> ts.ArrayType:
|
|
603
|
+
dimensions: Optional[int] = None
|
|
604
|
+
if model_kwargs is not None:
|
|
605
|
+
dimensions = model_kwargs.get('dimensions')
|
|
671
606
|
if dimensions is None:
|
|
672
607
|
if model not in _embedding_dimensions_cache:
|
|
673
608
|
# TODO: find some other way to retrieve a sample
|
|
@@ -682,14 +617,7 @@ def _(model: str, dimensions: Optional[int] = None) -> ts.ArrayType:
|
|
|
682
617
|
|
|
683
618
|
@pxt.udf
|
|
684
619
|
async def image_generations(
|
|
685
|
-
prompt: str,
|
|
686
|
-
*,
|
|
687
|
-
model: str = 'dall-e-2',
|
|
688
|
-
quality: Optional[str] = None,
|
|
689
|
-
size: Optional[str] = None,
|
|
690
|
-
style: Optional[str] = None,
|
|
691
|
-
user: Optional[str] = None,
|
|
692
|
-
timeout: Optional[float] = None,
|
|
620
|
+
prompt: str, *, model: str = 'dall-e-2', model_kwargs: Optional[dict[str, Any]] = None
|
|
693
621
|
) -> PIL.Image.Image:
|
|
694
622
|
"""
|
|
695
623
|
Creates an image given a prompt.
|
|
@@ -708,8 +636,8 @@ async def image_generations(
|
|
|
708
636
|
Args:
|
|
709
637
|
prompt: Prompt for the image.
|
|
710
638
|
model: The model to use for the generations.
|
|
711
|
-
|
|
712
|
-
|
|
639
|
+
model_kwargs: Additional keyword args for the OpenAI `images/generations` API. For details on the available
|
|
640
|
+
parameters, see: <https://platform.openai.com/docs/api-reference/images/create>
|
|
713
641
|
|
|
714
642
|
Returns:
|
|
715
643
|
The generated image.
|
|
@@ -720,16 +648,12 @@ async def image_generations(
|
|
|
720
648
|
|
|
721
649
|
>>> tbl.add_computed_column(gen_image=image_generations(tbl.text, model='dall-e-2'))
|
|
722
650
|
"""
|
|
651
|
+
if model_kwargs is None:
|
|
652
|
+
model_kwargs = {}
|
|
653
|
+
|
|
723
654
|
# TODO(aaron-siegel): Decompose CPU/GPU ops into separate functions
|
|
724
655
|
result = await _openai_client().images.generate(
|
|
725
|
-
prompt=prompt,
|
|
726
|
-
model=_opt(model),
|
|
727
|
-
quality=_opt(quality), # type: ignore
|
|
728
|
-
size=_opt(size), # type: ignore
|
|
729
|
-
style=_opt(style), # type: ignore
|
|
730
|
-
user=_opt(user),
|
|
731
|
-
response_format='b64_json',
|
|
732
|
-
timeout=_opt(timeout),
|
|
656
|
+
prompt=prompt, model=model, response_format='b64_json', **model_kwargs
|
|
733
657
|
)
|
|
734
658
|
b64_str = result.data[0].b64_json
|
|
735
659
|
b64_bytes = base64.b64decode(b64_str)
|
|
@@ -739,9 +663,11 @@ async def image_generations(
|
|
|
739
663
|
|
|
740
664
|
|
|
741
665
|
@image_generations.conditional_return_type
|
|
742
|
-
def _(
|
|
743
|
-
if
|
|
666
|
+
def _(model_kwargs: Optional[dict[str, Any]] = None) -> ts.ImageType:
|
|
667
|
+
if model_kwargs is None or 'size' not in model_kwargs:
|
|
668
|
+
# default size is 1024x1024
|
|
744
669
|
return ts.ImageType(size=(1024, 1024))
|
|
670
|
+
size = model_kwargs['size']
|
|
745
671
|
x_pos = size.find('x')
|
|
746
672
|
if x_pos == -1:
|
|
747
673
|
return ts.ImageType()
|
|
@@ -787,7 +713,7 @@ async def moderations(input: str, *, model: str = 'omni-moderation-latest') -> d
|
|
|
787
713
|
|
|
788
714
|
>>> tbl.add_computed_column(moderations=moderations(tbl.text, model='text-moderation-stable'))
|
|
789
715
|
"""
|
|
790
|
-
result = await _openai_client().moderations.create(input=input, model=
|
|
716
|
+
result = await _openai_client().moderations.create(input=input, model=model)
|
|
791
717
|
return result.dict()
|
|
792
718
|
|
|
793
719
|
|
|
@@ -826,15 +752,6 @@ def _openai_response_to_pxt_tool_calls(response: dict) -> Optional[dict]:
|
|
|
826
752
|
return pxt_tool_calls
|
|
827
753
|
|
|
828
754
|
|
|
829
|
-
_T = TypeVar('_T')
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
def _opt(arg: _T) -> Union[_T, 'openai.NotGiven']:
|
|
833
|
-
import openai
|
|
834
|
-
|
|
835
|
-
return arg if arg is not None else openai.NOT_GIVEN
|
|
836
|
-
|
|
837
|
-
|
|
838
755
|
__all__ = local_public_names(__name__)
|
|
839
756
|
|
|
840
757
|
|
pixeltable/functions/together.py
CHANGED
|
@@ -7,7 +7,7 @@ the [Working with Together AI](https://pixeltable.readme.io/docs/together-ai) tu
|
|
|
7
7
|
|
|
8
8
|
import base64
|
|
9
9
|
import io
|
|
10
|
-
from typing import TYPE_CHECKING, Callable, Optional, TypeVar
|
|
10
|
+
from typing import TYPE_CHECKING, Any, Callable, Optional, TypeVar
|
|
11
11
|
|
|
12
12
|
import numpy as np
|
|
13
13
|
import PIL.Image
|
|
@@ -50,21 +50,7 @@ def _retry(fn: Callable[..., T]) -> Callable[..., T]:
|
|
|
50
50
|
|
|
51
51
|
|
|
52
52
|
@pxt.udf(resource_pool='request-rate:together:chat')
|
|
53
|
-
async def completions(
|
|
54
|
-
prompt: str,
|
|
55
|
-
*,
|
|
56
|
-
model: str,
|
|
57
|
-
max_tokens: Optional[int] = None,
|
|
58
|
-
stop: Optional[list] = None,
|
|
59
|
-
temperature: Optional[float] = None,
|
|
60
|
-
top_p: Optional[float] = None,
|
|
61
|
-
top_k: Optional[int] = None,
|
|
62
|
-
repetition_penalty: Optional[float] = None,
|
|
63
|
-
logprobs: Optional[int] = None,
|
|
64
|
-
echo: Optional[bool] = None,
|
|
65
|
-
n: Optional[int] = None,
|
|
66
|
-
safety_model: Optional[str] = None,
|
|
67
|
-
) -> dict:
|
|
53
|
+
async def completions(prompt: str, *, model: str, model_kwargs: Optional[dict[str, Any]] = None) -> dict:
|
|
68
54
|
"""
|
|
69
55
|
Generate completions based on a given prompt using a specified model.
|
|
70
56
|
|
|
@@ -82,8 +68,8 @@ async def completions(
|
|
|
82
68
|
Args:
|
|
83
69
|
prompt: A string providing context for the model to complete.
|
|
84
70
|
model: The name of the model to query.
|
|
85
|
-
|
|
86
|
-
|
|
71
|
+
model_kwargs: Additional keyword arguments for the Together `completions` API.
|
|
72
|
+
For details on the available parameters, see: <https://docs.together.ai/reference/completions-1>
|
|
87
73
|
|
|
88
74
|
Returns:
|
|
89
75
|
A dictionary containing the response and other metadata.
|
|
@@ -94,41 +80,16 @@ async def completions(
|
|
|
94
80
|
|
|
95
81
|
>>> tbl.add_computed_column(response=completions(tbl.prompt, model='mistralai/Mixtral-8x7B-v0.1'))
|
|
96
82
|
"""
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
stop=stop,
|
|
102
|
-
temperature=temperature,
|
|
103
|
-
top_p=top_p,
|
|
104
|
-
top_k=top_k,
|
|
105
|
-
repetition_penalty=repetition_penalty,
|
|
106
|
-
logprobs=logprobs,
|
|
107
|
-
echo=echo,
|
|
108
|
-
n=n,
|
|
109
|
-
safety_model=safety_model,
|
|
110
|
-
)
|
|
83
|
+
if model_kwargs is None:
|
|
84
|
+
model_kwargs = {}
|
|
85
|
+
|
|
86
|
+
result = await _together_client().completions.create(prompt=prompt, model=model, **model_kwargs)
|
|
111
87
|
return result.dict()
|
|
112
88
|
|
|
113
89
|
|
|
114
90
|
@pxt.udf(resource_pool='request-rate:together:chat')
|
|
115
91
|
async def chat_completions(
|
|
116
|
-
messages: list[dict[str, str]],
|
|
117
|
-
*,
|
|
118
|
-
model: str,
|
|
119
|
-
max_tokens: Optional[int] = None,
|
|
120
|
-
stop: Optional[list[str]] = None,
|
|
121
|
-
temperature: Optional[float] = None,
|
|
122
|
-
top_p: Optional[float] = None,
|
|
123
|
-
top_k: Optional[int] = None,
|
|
124
|
-
repetition_penalty: Optional[float] = None,
|
|
125
|
-
logprobs: Optional[int] = None,
|
|
126
|
-
echo: Optional[bool] = None,
|
|
127
|
-
n: Optional[int] = None,
|
|
128
|
-
safety_model: Optional[str] = None,
|
|
129
|
-
response_format: Optional[dict] = None,
|
|
130
|
-
tools: Optional[dict] = None,
|
|
131
|
-
tool_choice: Optional[dict] = None,
|
|
92
|
+
messages: list[dict[str, str]], *, model: str, model_kwargs: Optional[dict[str, Any]] = None
|
|
132
93
|
) -> dict:
|
|
133
94
|
"""
|
|
134
95
|
Generate chat completions based on a given prompt using a specified model.
|
|
@@ -147,8 +108,8 @@ async def chat_completions(
|
|
|
147
108
|
Args:
|
|
148
109
|
messages: A list of messages comprising the conversation so far.
|
|
149
110
|
model: The name of the model to query.
|
|
150
|
-
|
|
151
|
-
|
|
111
|
+
model_kwargs: Additional keyword arguments for the Together `chat/completions` API.
|
|
112
|
+
For details on the available parameters, see: <https://docs.together.ai/reference/chat-completions-1>
|
|
152
113
|
|
|
153
114
|
Returns:
|
|
154
115
|
A dictionary containing the response and other metadata.
|
|
@@ -160,23 +121,10 @@ async def chat_completions(
|
|
|
160
121
|
>>> messages = [{'role': 'user', 'content': tbl.prompt}]
|
|
161
122
|
... tbl.add_computed_column(response=chat_completions(messages, model='mistralai/Mixtral-8x7B-v0.1'))
|
|
162
123
|
"""
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
stop=stop,
|
|
168
|
-
temperature=temperature,
|
|
169
|
-
top_p=top_p,
|
|
170
|
-
top_k=top_k,
|
|
171
|
-
repetition_penalty=repetition_penalty,
|
|
172
|
-
logprobs=logprobs,
|
|
173
|
-
echo=echo,
|
|
174
|
-
n=n,
|
|
175
|
-
safety_model=safety_model,
|
|
176
|
-
response_format=response_format,
|
|
177
|
-
tools=tools,
|
|
178
|
-
tool_choice=tool_choice,
|
|
179
|
-
)
|
|
124
|
+
if model_kwargs is None:
|
|
125
|
+
model_kwargs = {}
|
|
126
|
+
|
|
127
|
+
result = await _together_client().chat.completions.create(messages=messages, model=model, **model_kwargs)
|
|
180
128
|
return result.dict()
|
|
181
129
|
|
|
182
130
|
|
|
@@ -236,14 +184,7 @@ def _(model: str) -> ts.ArrayType:
|
|
|
236
184
|
|
|
237
185
|
@pxt.udf(resource_pool='request-rate:together:images')
|
|
238
186
|
async def image_generations(
|
|
239
|
-
prompt: str,
|
|
240
|
-
*,
|
|
241
|
-
model: str,
|
|
242
|
-
steps: Optional[int] = None,
|
|
243
|
-
seed: Optional[int] = None,
|
|
244
|
-
height: Optional[int] = None,
|
|
245
|
-
width: Optional[int] = None,
|
|
246
|
-
negative_prompt: Optional[str] = None,
|
|
187
|
+
prompt: str, *, model: str, model_kwargs: Optional[dict[str, Any]] = None
|
|
247
188
|
) -> PIL.Image.Image:
|
|
248
189
|
"""
|
|
249
190
|
Generate images based on a given prompt using a specified model.
|
|
@@ -262,8 +203,8 @@ async def image_generations(
|
|
|
262
203
|
Args:
|
|
263
204
|
prompt: A description of the desired images.
|
|
264
205
|
model: The model to use for image generation.
|
|
265
|
-
|
|
266
|
-
|
|
206
|
+
model_kwargs: Additional keyword args for the Together `images/generations` API.
|
|
207
|
+
For details on the available parameters, see: <https://docs.together.ai/reference/post_images-generations>
|
|
267
208
|
|
|
268
209
|
Returns:
|
|
269
210
|
The generated image.
|
|
@@ -276,9 +217,10 @@ async def image_generations(
|
|
|
276
217
|
... response=image_generations(tbl.prompt, model='stabilityai/stable-diffusion-xl-base-1.0')
|
|
277
218
|
... )
|
|
278
219
|
"""
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
220
|
+
if model_kwargs is None:
|
|
221
|
+
model_kwargs = {}
|
|
222
|
+
|
|
223
|
+
result = await _together_client().images.generate(prompt=prompt, model=model, **model_kwargs)
|
|
282
224
|
if result.data[0].b64_json is not None:
|
|
283
225
|
b64_bytes = base64.b64decode(result.data[0].b64_json)
|
|
284
226
|
img = PIL.Image.open(io.BytesIO(b64_bytes))
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: pixeltable
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.0rc3
|
|
4
4
|
Summary: AI Data Infrastructure: Declarative, Multimodal, and Incremental
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
Keywords: data-science,machine-learning,database,ai,computer-vision,chatbot,ml,artificial-intelligence,feature-engineering,multimodal,mlops,feature-store,vector-database,llm,genai
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
pixeltable/__init__.py,sha256=-uXHuiXH98kAlCupUTPbkBh4ToZgxcYUOk7-c9hqCC8,1439
|
|
2
|
-
pixeltable/__version__.py,sha256=
|
|
2
|
+
pixeltable/__version__.py,sha256=l1gVhW4YjeNouBt4ti5Rxsd1ETc8Ls5nKRC8aMceXrM,120
|
|
3
3
|
pixeltable/catalog/__init__.py,sha256=rQmjveID4bk6NI4Ql09lGsZ0K0HVE2l1yqKAveipHzc,558
|
|
4
4
|
pixeltable/catalog/catalog.py,sha256=ExHm2bbAs_4-T6zq3ow2fQ5a9Zja6G3WzHoo3Qk0X40,59399
|
|
5
5
|
pixeltable/catalog/column.py,sha256=v3SE6CQs_ZXTDkBeiJ7gu9sxBJD-6EbkjsB1TZvLSJI,11280
|
|
@@ -78,26 +78,26 @@ pixeltable/func/signature.py,sha256=0PI6xdhLgwy9-GMkzkm7GlsBnsNMiS9aoNI9LWXwvN0,
|
|
|
78
78
|
pixeltable/func/tools.py,sha256=bmHnnd9lXkQ8sYHp5RSMF56NimSTE3uhG2xbIxs4Np4,5726
|
|
79
79
|
pixeltable/func/udf.py,sha256=qQfaX1O3ZhUvSgiNnitW7nRKnZFJ5yu_Fj9ioqQgjqg,13219
|
|
80
80
|
pixeltable/functions/__init__.py,sha256=x_ZodeEtayD2XDjlDZE4L_QTzajF6riftIc5P4ZjEiY,578
|
|
81
|
-
pixeltable/functions/anthropic.py,sha256=
|
|
81
|
+
pixeltable/functions/anthropic.py,sha256=G2E0sH5vP933eZZxhz1tOByy5cg6N2XPvhSqIBzqufo,8782
|
|
82
82
|
pixeltable/functions/audio.py,sha256=7bsm4igQEW7RYSrSevwqaUOqyEnvBbPbJ8c-VknDl1E,657
|
|
83
83
|
pixeltable/functions/bedrock.py,sha256=lTCFHjYunF3minBGWcjXR90yJ8resFjXr4niyKhfxms,4217
|
|
84
84
|
pixeltable/functions/date.py,sha256=WUwqyrOWB8A00cTNEd6Vd7anQZo40_-7EWhpfpI-P6c,5323
|
|
85
|
-
pixeltable/functions/deepseek.py,sha256=
|
|
86
|
-
pixeltable/functions/fireworks.py,sha256=
|
|
87
|
-
pixeltable/functions/gemini.py,sha256
|
|
85
|
+
pixeltable/functions/deepseek.py,sha256=IAo2e_DhkM0A5NrskxuPQUGYzIYAl4do_mdO1Qc3PeY,3338
|
|
86
|
+
pixeltable/functions/fireworks.py,sha256=q7eWlYfiWbA0d9r3CB_NAe1fw3q-Z7qsw2gyGJNgWLQ,4786
|
|
87
|
+
pixeltable/functions/gemini.py,sha256=ZsbySkoMdOgZEUfFUccDbIdrbLb6DGRxzD88fHW-cRI,8317
|
|
88
88
|
pixeltable/functions/globals.py,sha256=ZXBV2LPXT2-yQYHHE7q8N1WdAr0WxiIO1ax0qwxhmK8,5118
|
|
89
89
|
pixeltable/functions/huggingface.py,sha256=KM1OH0Jt6XWF2jfpHb6rGhi1mV-AQNYAsHAyQfzW4qw,20560
|
|
90
90
|
pixeltable/functions/image.py,sha256=IKXljMma-uU88efptC3F4aywau7DYcD-Nqd3YpmRNRw,13971
|
|
91
91
|
pixeltable/functions/json.py,sha256=d7-AvwytUQtQYF_JnWJkptT_Yq0NgMpWfVk-m3U6qTY,807
|
|
92
|
-
pixeltable/functions/llama_cpp.py,sha256=
|
|
92
|
+
pixeltable/functions/llama_cpp.py,sha256=1QB4vQ7J4Za1mL93bRIBXgokNtpzzYr_QU6KF27i9xo,3919
|
|
93
93
|
pixeltable/functions/math.py,sha256=eZEFjXxNHDHjcCsOMhzfNbJthTsmtNxtSFV8AEeRIfM,4979
|
|
94
|
-
pixeltable/functions/mistralai.py,sha256=
|
|
95
|
-
pixeltable/functions/ollama.py,sha256=
|
|
96
|
-
pixeltable/functions/openai.py,sha256=
|
|
94
|
+
pixeltable/functions/mistralai.py,sha256=PTXQegC2LO5Pw0zXBO_SVV7I2c5qBvqVVgfm_mK1ir0,5845
|
|
95
|
+
pixeltable/functions/ollama.py,sha256=4-6h9Foq_7Ut7JtEHGkeg1KbuKaFywSuMrKiw0xAyCA,4231
|
|
96
|
+
pixeltable/functions/openai.py,sha256=kzi8HApD971O54Xl82G0jI7n0E2ui476kV1wAKObx88,27768
|
|
97
97
|
pixeltable/functions/replicate.py,sha256=SLMPNi44QMa16TVTImZRkNMXXyRZ0mmpnK6P5uXQE0k,2467
|
|
98
98
|
pixeltable/functions/string.py,sha256=LdBNOna5PUSPmM5VlJ_qhmwzyFhumW0k6Dvx2rXSZtc,25356
|
|
99
99
|
pixeltable/functions/timestamp.py,sha256=0zp4urJagCcNLfJE0ltTCft-J9qs2C716TmRngKYaa0,9171
|
|
100
|
-
pixeltable/functions/together.py,sha256=
|
|
100
|
+
pixeltable/functions/together.py,sha256=A8J19BXywyWQ6a2_n05-8uIG5jquOBGqPmW3mb-NrIc,8842
|
|
101
101
|
pixeltable/functions/util.py,sha256=lVya13gcao8T34OGX7zy1cglQPNwaBbSBw57bVPyHNs,745
|
|
102
102
|
pixeltable/functions/video.py,sha256=jS4YhMofD448YhGtI6ZXBAkeGw_AYYQTN0AbgHh_hok,6933
|
|
103
103
|
pixeltable/functions/vision.py,sha256=_a0wY3akkVhWnnxlq__1VzSLylytlNadpNOOPOwSfLk,15393
|
|
@@ -182,8 +182,8 @@ pixeltable/utils/s3.py,sha256=pxip2MlCqd2Qon2dzJXzfxvwtZyc-BAsjAnLL4J_OXY,587
|
|
|
182
182
|
pixeltable/utils/sample.py,sha256=Pj8oSZw0WsdASD1BpTtKiWP4cwef7KQqVAfIFKlJNxA,643
|
|
183
183
|
pixeltable/utils/sql.py,sha256=Sa4Lh-VGe8GToU5W7DRiWf2lMl9B6saPqemiT0ZdHEc,806
|
|
184
184
|
pixeltable/utils/transactional_directory.py,sha256=OFKmu90oP7KwBAljwjnzP_w8euGdAXob3y4Nx9SCNHA,1357
|
|
185
|
-
pixeltable-0.4.
|
|
186
|
-
pixeltable-0.4.
|
|
187
|
-
pixeltable-0.4.
|
|
188
|
-
pixeltable-0.4.
|
|
189
|
-
pixeltable-0.4.
|
|
185
|
+
pixeltable-0.4.0rc3.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
186
|
+
pixeltable-0.4.0rc3.dist-info/METADATA,sha256=iRhLy9JQXIsjwIOKQnvJBQCJuGfh_Xc56W3dcgWGs-A,20580
|
|
187
|
+
pixeltable-0.4.0rc3.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
188
|
+
pixeltable-0.4.0rc3.dist-info/entry_points.txt,sha256=ToOd-pRgG7AitEBgYoBCRRB4-KVDQ0pj_9T4a1LgwA4,97
|
|
189
|
+
pixeltable-0.4.0rc3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|