@modular-prompt/driver 0.14.0 → 0.16.0
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.
- package/README.md +90 -5
- package/dist/driver-registry/ai-service.d.ts +23 -1
- package/dist/driver-registry/ai-service.d.ts.map +1 -1
- package/dist/driver-registry/ai-service.js +44 -10
- package/dist/driver-registry/ai-service.js.map +1 -1
- package/dist/driver-registry/config-based-factory.d.ts.map +1 -1
- package/dist/driver-registry/config-based-factory.js +20 -3
- package/dist/driver-registry/config-based-factory.js.map +1 -1
- package/dist/driver-registry/factory-helper.d.ts +2 -0
- package/dist/driver-registry/factory-helper.d.ts.map +1 -1
- package/dist/driver-registry/factory-helper.js +22 -3
- package/dist/driver-registry/factory-helper.js.map +1 -1
- package/dist/driver-registry/index.d.ts +2 -2
- package/dist/driver-registry/index.d.ts.map +1 -1
- package/dist/driver-registry/index.js +1 -1
- package/dist/driver-registry/index.js.map +1 -1
- package/dist/driver-registry/registry.d.ts.map +1 -1
- package/dist/driver-registry/registry.js +3 -1
- package/dist/driver-registry/registry.js.map +1 -1
- package/dist/driver-registry/types.d.ts +11 -2
- package/dist/driver-registry/types.d.ts.map +1 -1
- package/dist/index.d.ts +10 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/local-inference/adapters.d.ts +66 -0
- package/dist/local-inference/adapters.d.ts.map +1 -0
- package/dist/local-inference/adapters.js +2 -0
- package/dist/local-inference/adapters.js.map +1 -0
- package/dist/local-inference/driver.d.ts +51 -0
- package/dist/local-inference/driver.d.ts.map +1 -0
- package/dist/local-inference/driver.js +309 -0
- package/dist/local-inference/driver.js.map +1 -0
- package/dist/local-inference/index.d.ts +22 -0
- package/dist/local-inference/index.d.ts.map +1 -0
- package/dist/local-inference/index.js +17 -0
- package/dist/local-inference/index.js.map +1 -0
- package/dist/local-inference/process-client.d.ts +50 -0
- package/dist/local-inference/process-client.d.ts.map +1 -0
- package/dist/local-inference/process-client.js +92 -0
- package/dist/local-inference/process-client.js.map +1 -0
- package/dist/local-inference/process-communication.d.ts +41 -0
- package/dist/local-inference/process-communication.d.ts.map +1 -0
- package/dist/{mlx-ml/process → local-inference}/process-communication.js +25 -61
- package/dist/local-inference/process-communication.js.map +1 -0
- package/dist/local-inference/process-port.d.ts +12 -0
- package/dist/local-inference/process-port.d.ts.map +1 -0
- package/dist/local-inference/process-port.js +2 -0
- package/dist/local-inference/process-port.js.map +1 -0
- package/dist/local-inference/prompt-utils.d.ts +6 -0
- package/dist/local-inference/prompt-utils.d.ts.map +1 -0
- package/dist/local-inference/prompt-utils.js +17 -0
- package/dist/local-inference/prompt-utils.js.map +1 -0
- package/dist/local-inference/protocol.d.ts +192 -0
- package/dist/local-inference/protocol.d.ts.map +1 -0
- package/dist/local-inference/protocol.js +2 -0
- package/dist/local-inference/protocol.js.map +1 -0
- package/dist/local-inference/queue-types.d.ts +54 -0
- package/dist/local-inference/queue-types.d.ts.map +1 -0
- package/dist/local-inference/queue-types.js +2 -0
- package/dist/local-inference/queue-types.js.map +1 -0
- package/dist/local-inference/request-queue.d.ts +36 -0
- package/dist/local-inference/request-queue.d.ts.map +1 -0
- package/dist/{mlx-ml/process/queue.js → local-inference/request-queue.js} +83 -56
- package/dist/local-inference/request-queue.js.map +1 -0
- package/dist/local-inference/stream-utils.d.ts +19 -0
- package/dist/local-inference/stream-utils.d.ts.map +1 -0
- package/dist/local-inference/stream-utils.js +76 -0
- package/dist/local-inference/stream-utils.js.map +1 -0
- package/dist/mlx-ml/mlx-cache-controller.d.ts.map +1 -1
- package/dist/mlx-ml/mlx-cache-controller.js +2 -1
- package/dist/mlx-ml/mlx-cache-controller.js.map +1 -1
- package/dist/mlx-ml/mlx-cache-support.d.ts +23 -0
- package/dist/mlx-ml/mlx-cache-support.d.ts.map +1 -0
- package/dist/mlx-ml/mlx-cache-support.js +45 -0
- package/dist/mlx-ml/mlx-cache-support.js.map +1 -0
- package/dist/mlx-ml/mlx-driver.d.ts +20 -59
- package/dist/mlx-ml/mlx-driver.d.ts.map +1 -1
- package/dist/mlx-ml/mlx-driver.js +86 -460
- package/dist/mlx-ml/mlx-driver.js.map +1 -1
- package/dist/mlx-ml/mlx-local-inference-adapters.d.ts +3 -0
- package/dist/mlx-ml/mlx-local-inference-adapters.d.ts.map +1 -0
- package/dist/mlx-ml/mlx-local-inference-adapters.js +19 -0
- package/dist/mlx-ml/mlx-local-inference-adapters.js.map +1 -0
- package/dist/mlx-ml/mlx-options.d.ts +19 -0
- package/dist/mlx-ml/mlx-options.d.ts.map +1 -0
- package/dist/mlx-ml/mlx-options.js +30 -0
- package/dist/mlx-ml/mlx-options.js.map +1 -0
- package/dist/mlx-ml/process/index.d.ts +10 -8
- package/dist/mlx-ml/process/index.d.ts.map +1 -1
- package/dist/mlx-ml/process/index.js +73 -54
- package/dist/mlx-ml/process/index.js.map +1 -1
- package/dist/mlx-ml/process/model-specific.d.ts +2 -1
- package/dist/mlx-ml/process/model-specific.d.ts.map +1 -1
- package/dist/mlx-ml/process/model-specific.js.map +1 -1
- package/dist/mlx-ml/process/prompt-builder.d.ts +11 -0
- package/dist/mlx-ml/process/prompt-builder.d.ts.map +1 -0
- package/dist/mlx-ml/process/prompt-builder.js +51 -0
- package/dist/mlx-ml/process/prompt-builder.js.map +1 -0
- package/dist/mlx-ml/process/types.d.ts +15 -183
- package/dist/mlx-ml/process/types.d.ts.map +1 -1
- package/dist/mlx-ml/types.d.ts +2 -45
- package/dist/mlx-ml/types.d.ts.map +1 -1
- package/dist/models-config/index.d.ts +8 -0
- package/dist/models-config/index.d.ts.map +1 -0
- package/dist/models-config/index.js +7 -0
- package/dist/models-config/index.js.map +1 -0
- package/dist/models-config/loader.d.ts +20 -0
- package/dist/models-config/loader.d.ts.map +1 -0
- package/dist/models-config/loader.js +85 -0
- package/dist/models-config/loader.js.map +1 -0
- package/dist/models-config/paths.d.ts +15 -0
- package/dist/models-config/paths.d.ts.map +1 -0
- package/dist/models-config/paths.js +26 -0
- package/dist/models-config/paths.js.map +1 -0
- package/dist/models-config/resolve.d.ts +57 -0
- package/dist/models-config/resolve.d.ts.map +1 -0
- package/dist/models-config/resolve.js +208 -0
- package/dist/models-config/resolve.js.map +1 -0
- package/dist/models-config/types.d.ts +62 -0
- package/dist/models-config/types.d.ts.map +1 -0
- package/dist/models-config/types.js +5 -0
- package/dist/models-config/types.js.map +1 -0
- package/dist/pytorch/process/index.d.ts +35 -0
- package/dist/pytorch/process/index.d.ts.map +1 -0
- package/dist/pytorch/process/index.js +69 -0
- package/dist/pytorch/process/index.js.map +1 -0
- package/dist/pytorch/pytorch-driver.d.ts +35 -0
- package/dist/pytorch/pytorch-driver.d.ts.map +1 -0
- package/dist/pytorch/pytorch-driver.js +48 -0
- package/dist/pytorch/pytorch-driver.js.map +1 -0
- package/dist/pytorch/pytorch-local-inference-adapters.d.ts +3 -0
- package/dist/pytorch/pytorch-local-inference-adapters.d.ts.map +1 -0
- package/dist/pytorch/pytorch-local-inference-adapters.js +19 -0
- package/dist/pytorch/pytorch-local-inference-adapters.js.map +1 -0
- package/dist/pytorch/pytorch-options.d.ts +8 -0
- package/dist/pytorch/pytorch-options.d.ts.map +1 -0
- package/dist/pytorch/pytorch-options.js +21 -0
- package/dist/pytorch/pytorch-options.js.map +1 -0
- package/dist/query-logger.js +1 -1
- package/dist/query-logger.js.map +1 -1
- package/dist/runtime/check.d.ts +10 -0
- package/dist/runtime/check.d.ts.map +1 -0
- package/dist/runtime/check.js +25 -0
- package/dist/runtime/check.js.map +1 -0
- package/dist/runtime/index.d.ts +5 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +5 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/manifest-core.d.mts +27 -0
- package/dist/runtime/manifest-core.d.mts.map +1 -0
- package/dist/runtime/manifest-core.mjs +68 -0
- package/dist/runtime/manifest-core.mjs.map +1 -0
- package/dist/runtime/manifest.d.ts +18 -0
- package/dist/runtime/manifest.d.ts.map +1 -0
- package/dist/runtime/manifest.js +9 -0
- package/dist/runtime/manifest.js.map +1 -0
- package/dist/runtime/paths-core.d.mts +17 -0
- package/dist/runtime/paths-core.d.mts.map +1 -0
- package/dist/runtime/paths-core.mjs +67 -0
- package/dist/runtime/paths-core.mjs.map +1 -0
- package/dist/runtime/paths.d.ts +12 -0
- package/dist/runtime/paths.d.ts.map +1 -0
- package/dist/runtime/paths.js +17 -0
- package/dist/runtime/paths.js.map +1 -0
- package/dist/runtime/setup-commands-core.d.mts +13 -0
- package/dist/runtime/setup-commands-core.d.mts.map +1 -0
- package/dist/runtime/setup-commands-core.mjs +14 -0
- package/dist/runtime/setup-commands-core.mjs.map +1 -0
- package/dist/runtime/setup-commands.d.ts +2 -0
- package/dist/runtime/setup-commands.d.ts.map +1 -0
- package/dist/runtime/setup-commands.js +2 -0
- package/dist/runtime/setup-commands.js.map +1 -0
- package/dist/types.d.ts +11 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +13 -7
- package/scripts/download-model.js +26 -9
- package/scripts/runtime-cli.js +320 -0
- package/src/mlx-ml/python/__main__.py +43 -4
- package/src/mlx-ml/python/backends/cache_archive.py +41 -0
- package/src/mlx-ml/python/backends/mlx_lm.py +17 -1
- package/src/mlx-ml/python/handlers/__init__.py +2 -1
- package/src/mlx-ml/python/handlers/completion.py +3 -27
- package/src/mlx-ml/python/handlers/{chat.py → generate.py} +33 -106
- package/src/mlx-ml/python/handlers/render.py +40 -0
- package/src/mlx-ml/python/pyproject.toml +11 -4
- package/src/mlx-ml/python/server.py +28 -8
- package/src/mlx-ml/python/utils/template_render.py +80 -0
- package/src/mlx-ml/python/utils/token_utils.py +2 -2
- package/src/mlx-ml/python/uv.lock +544 -689
- package/src/pytorch/python/__main__.py +19 -0
- package/src/pytorch/python/backends/__init__.py +3 -0
- package/src/pytorch/python/backends/base.py +84 -0
- package/src/pytorch/python/backends/transformers_lm.py +127 -0
- package/src/pytorch/python/handlers/__init__.py +6 -0
- package/src/pytorch/python/handlers/cancel.py +53 -0
- package/src/pytorch/python/handlers/capabilities.py +6 -0
- package/src/pytorch/python/handlers/completion.py +15 -0
- package/src/pytorch/python/handlers/format_test.py +70 -0
- package/src/pytorch/python/handlers/generate.py +68 -0
- package/src/pytorch/python/handlers/render.py +40 -0
- package/src/pytorch/python/handlers/tokenize.py +63 -0
- package/src/pytorch/python/pyproject.toml +36 -0
- package/src/pytorch/python/server.py +140 -0
- package/src/pytorch/python/utils/__init__.py +0 -0
- package/src/pytorch/python/utils/chat_template_constraints.py +164 -0
- package/src/pytorch/python/utils/prompt_builder.py +54 -0
- package/src/pytorch/python/utils/template_render.py +80 -0
- package/src/pytorch/python/utils/token_utils.py +376 -0
- package/src/pytorch/python/uv.lock +694 -0
- package/dist/mlx-ml/process/process-communication.d.ts +0 -45
- package/dist/mlx-ml/process/process-communication.d.ts.map +0 -1
- package/dist/mlx-ml/process/process-communication.js.map +0 -1
- package/dist/mlx-ml/process/queue.d.ts +0 -35
- package/dist/mlx-ml/process/queue.d.ts.map +0 -1
- package/dist/mlx-ml/process/queue.js.map +0 -1
- package/scripts/setup-mlx.js +0 -53
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import json
|
|
4
|
+
import os
|
|
4
5
|
import re
|
|
5
6
|
import sys
|
|
6
7
|
|
|
7
8
|
from backends.base import ModelBackend
|
|
8
9
|
from mlx_lm.models.cache import trim_prompt_cache
|
|
9
|
-
from utils.prompt_builder import generate_merged_prompt, supports_chat_template
|
|
10
10
|
from handlers.cancel import poll_cancel
|
|
11
11
|
|
|
12
12
|
|
|
@@ -53,65 +53,42 @@ def _stream_to_stdout(
|
|
|
53
53
|
print("", end="\0", flush=True)
|
|
54
54
|
|
|
55
55
|
|
|
56
|
-
def
|
|
56
|
+
def handle_generate(
|
|
57
57
|
backend: ModelBackend,
|
|
58
|
-
|
|
59
|
-
messages: list,
|
|
60
|
-
primer: str | None = None,
|
|
58
|
+
prompt: str | list[int],
|
|
61
59
|
options: dict | None = None,
|
|
62
|
-
tools: list | None = None,
|
|
63
60
|
images: list | None = None,
|
|
64
61
|
max_image_size: int = 768,
|
|
65
|
-
|
|
62
|
+
primer: str | None = None,
|
|
66
63
|
cache_path: str | None = None,
|
|
67
64
|
cache_trim_tokens: int | None = None,
|
|
68
65
|
) -> None:
|
|
69
|
-
"""
|
|
66
|
+
"""LIP generate: 整形済み prompt のストリーム推論"""
|
|
70
67
|
if options is None:
|
|
71
68
|
options = {}
|
|
72
69
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if backend.supports_vision():
|
|
76
|
-
add_generation_prompt = True
|
|
77
|
-
fmt_messages = list(messages)
|
|
78
|
-
if primer is not None:
|
|
79
|
-
fmt_messages.append({"role": "assistant", "content": primer})
|
|
80
|
-
add_generation_prompt = False
|
|
81
|
-
|
|
82
|
-
try:
|
|
83
|
-
prompt = tokenizer.apply_chat_template(
|
|
84
|
-
fmt_messages,
|
|
85
|
-
tools=tools,
|
|
86
|
-
add_generation_prompt=add_generation_prompt,
|
|
87
|
-
tokenize=False,
|
|
88
|
-
)
|
|
89
|
-
except TypeError:
|
|
90
|
-
prompt = tokenizer.apply_chat_template(
|
|
91
|
-
fmt_messages,
|
|
92
|
-
add_generation_prompt=add_generation_prompt,
|
|
93
|
-
tokenize=False,
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
if primer is not None:
|
|
97
|
-
prompt = primer.join(prompt.split(primer)[0:-1]) + primer
|
|
98
|
-
|
|
99
|
-
display_prompt = re.sub(r'(<\|image_pad\|>)+', '<|image_pad|>...', prompt)
|
|
100
|
-
sys.stderr.write(f"--- vlm prompt (images: {len(images) if images else 0}, max_size: {max_image_size})\n{display_prompt}\n")
|
|
101
|
-
|
|
102
|
-
final_options = dict(options)
|
|
70
|
+
final_options = dict(options)
|
|
71
|
+
if images:
|
|
103
72
|
final_options["max_image_size"] = max_image_size
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
73
|
+
if os.getenv('MLX_DEBUG'):
|
|
74
|
+
if isinstance(prompt, str):
|
|
75
|
+
display_prompt = re.sub(r'(<\|image_pad\|>)+', '<|image_pad|>...', prompt)
|
|
76
|
+
else:
|
|
77
|
+
display_prompt = f"<token ids: len={len(prompt)}>"
|
|
78
|
+
sys.stderr.write(
|
|
79
|
+
f"--- vlm generate (images: {len(images)}, max_size: {max_image_size})\n{display_prompt}\n"
|
|
80
|
+
)
|
|
81
|
+
elif os.getenv('MLX_DEBUG'):
|
|
82
|
+
if isinstance(prompt, list):
|
|
83
|
+
sys.stderr.write(f"--- prompt: len={len(prompt)}\n")
|
|
84
|
+
else:
|
|
85
|
+
sys.stderr.write(f"--- prompt\n{prompt}\n")
|
|
112
86
|
|
|
113
|
-
|
|
87
|
+
# VLM 経路では KV キャッシュを使わない(旧 chat ハンドラと同様)
|
|
88
|
+
prompt_cache = None
|
|
114
89
|
cache_tokens = 0
|
|
90
|
+
if cache_path and not images:
|
|
91
|
+
prompt_cache = backend.load_cache_from_file(cache_path)
|
|
115
92
|
if prompt_cache is not None:
|
|
116
93
|
if cache_trim_tokens is not None:
|
|
117
94
|
current_offset = backend.get_cache_offset(prompt_cache)
|
|
@@ -128,7 +105,6 @@ def handle_chat(
|
|
|
128
105
|
if meta_count is not None:
|
|
129
106
|
cache_tokens = meta_count
|
|
130
107
|
else:
|
|
131
|
-
# Legacy cache without meta file - skip it for safety
|
|
132
108
|
sys.stderr.write(
|
|
133
109
|
f"WARNING: Cache file exists but no .meta.json found at {cache_path}. "
|
|
134
110
|
"Ignoring cache for safety (may be from old implementation).\n"
|
|
@@ -142,67 +118,11 @@ def handle_chat(
|
|
|
142
118
|
elif cache_path:
|
|
143
119
|
sys.stderr.write(f"KV cache load FAILED: {cache_path}\n")
|
|
144
120
|
|
|
145
|
-
if not supports_chat_template(tokenizer):
|
|
146
|
-
prompt = generate_merged_prompt(messages, capabilities)
|
|
147
|
-
if prompt_cache is not None:
|
|
148
|
-
sys.stderr.write("KV cache ignored: model does not support chat template\n")
|
|
149
|
-
_stream_to_stdout(backend, prompt, options, primer=primer)
|
|
150
|
-
return
|
|
151
|
-
|
|
152
|
-
add_generation_prompt = True
|
|
153
|
-
fmt_messages = list(messages)
|
|
154
|
-
if primer is not None:
|
|
155
|
-
fmt_messages.append({"role": "assistant", "content": primer})
|
|
156
|
-
add_generation_prompt = False
|
|
157
|
-
|
|
158
|
-
extra_kwargs = {}
|
|
159
|
-
if tools is not None:
|
|
160
|
-
extra_kwargs["tools"] = tools
|
|
161
|
-
if reasoning_effort is not None:
|
|
162
|
-
extra_kwargs["reasoning_effort"] = reasoning_effort
|
|
163
|
-
|
|
164
|
-
trust_remote_code = options.get("trust_remote_code")
|
|
165
|
-
if trust_remote_code is not None:
|
|
166
|
-
extra_kwargs["trust_remote_code"] = trust_remote_code
|
|
167
|
-
|
|
168
|
-
try:
|
|
169
|
-
prompt = tokenizer.apply_chat_template(
|
|
170
|
-
fmt_messages,
|
|
171
|
-
add_generation_prompt=add_generation_prompt,
|
|
172
|
-
tokenize=False,
|
|
173
|
-
**extra_kwargs,
|
|
174
|
-
)
|
|
175
|
-
except TypeError:
|
|
176
|
-
try:
|
|
177
|
-
fallback_kwargs = {}
|
|
178
|
-
if tools is not None:
|
|
179
|
-
fallback_kwargs["tools"] = tools
|
|
180
|
-
prompt = tokenizer.apply_chat_template(
|
|
181
|
-
fmt_messages,
|
|
182
|
-
add_generation_prompt=add_generation_prompt,
|
|
183
|
-
tokenize=False,
|
|
184
|
-
**fallback_kwargs,
|
|
185
|
-
)
|
|
186
|
-
except TypeError:
|
|
187
|
-
prompt = tokenizer.apply_chat_template(
|
|
188
|
-
fmt_messages,
|
|
189
|
-
add_generation_prompt=add_generation_prompt,
|
|
190
|
-
tokenize=False,
|
|
191
|
-
)
|
|
192
|
-
|
|
193
|
-
if primer is not None:
|
|
194
|
-
prompt = primer.join(prompt.split(primer)[0:-1]) + primer
|
|
195
|
-
|
|
196
|
-
if isinstance(prompt, list):
|
|
197
|
-
sys.stderr.write(f"--- prompt: len={len(prompt)}\n")
|
|
198
|
-
else:
|
|
199
|
-
sys.stderr.write(f"--- prompt\n{prompt}\n")
|
|
200
|
-
|
|
201
|
-
final_options = dict(options)
|
|
202
121
|
final_options.pop("trust_remote_code", None)
|
|
203
122
|
|
|
204
123
|
effective_prompt = prompt
|
|
205
124
|
if prompt_cache is not None and cache_tokens > 0 and isinstance(prompt, str):
|
|
125
|
+
tokenizer = backend.get_tokenizer()
|
|
206
126
|
add_special = tokenizer.bos_token is None or not prompt.startswith(
|
|
207
127
|
tokenizer.bos_token
|
|
208
128
|
)
|
|
@@ -221,4 +141,11 @@ def handle_chat(
|
|
|
221
141
|
)
|
|
222
142
|
prompt_cache = None
|
|
223
143
|
|
|
224
|
-
_stream_to_stdout(
|
|
144
|
+
_stream_to_stdout(
|
|
145
|
+
backend,
|
|
146
|
+
effective_prompt,
|
|
147
|
+
final_options,
|
|
148
|
+
images=images,
|
|
149
|
+
primer=primer,
|
|
150
|
+
prompt_cache=prompt_cache,
|
|
151
|
+
)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
|
|
5
|
+
from backends.base import ModelBackend
|
|
6
|
+
from utils.template_render import apply_chat_template_prompt
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def handle_render(
|
|
10
|
+
backend: ModelBackend,
|
|
11
|
+
messages: list,
|
|
12
|
+
options: dict | None = None,
|
|
13
|
+
tools: list | None = None,
|
|
14
|
+
reasoning_effort: str | None = None,
|
|
15
|
+
) -> None:
|
|
16
|
+
"""LIP render: apply_chat_template のみ(推論しない)"""
|
|
17
|
+
if options is None:
|
|
18
|
+
options = {}
|
|
19
|
+
|
|
20
|
+
result: dict = {
|
|
21
|
+
"formatted_prompt": None,
|
|
22
|
+
"error": None,
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
trust_remote_code = options.get("trust_remote_code")
|
|
27
|
+
primer = options.get("primer")
|
|
28
|
+
prompt = apply_chat_template_prompt(
|
|
29
|
+
backend,
|
|
30
|
+
messages,
|
|
31
|
+
primer=primer,
|
|
32
|
+
tools=tools,
|
|
33
|
+
reasoning_effort=reasoning_effort,
|
|
34
|
+
trust_remote_code=trust_remote_code,
|
|
35
|
+
)
|
|
36
|
+
result["formatted_prompt"] = prompt
|
|
37
|
+
except Exception as e:
|
|
38
|
+
result["error"] = str(e)
|
|
39
|
+
|
|
40
|
+
print(json.dumps(result), end="\0", flush=True)
|
|
@@ -2,18 +2,25 @@
|
|
|
2
2
|
name = "mlx_driver"
|
|
3
3
|
version = "0.1.0"
|
|
4
4
|
description = "MLX driver for moduler-prompt"
|
|
5
|
-
requires-python = ">=3.
|
|
5
|
+
requires-python = ">=3.11,<3.14"
|
|
6
6
|
dependencies = [
|
|
7
7
|
"flex==6.14.1",
|
|
8
8
|
"hf-xet==1.2.0",
|
|
9
9
|
"jinja2==3.1.6",
|
|
10
|
-
"mlx>=0.
|
|
10
|
+
"mlx>=0.32.2; sys_platform == 'darwin'",
|
|
11
11
|
"mlx-lm==0.31.3; sys_platform == 'darwin'",
|
|
12
|
-
"mlx-
|
|
12
|
+
"mlx-optiq>=0.4.4; sys_platform == 'darwin'",
|
|
13
|
+
"mlx-vlm==0.6.17; sys_platform == 'darwin'",
|
|
13
14
|
"tokenizers==0.22.2",
|
|
14
15
|
"torch==2.9.1",
|
|
15
16
|
"torchvision==0.24.1",
|
|
16
|
-
"transformers>=5.
|
|
17
|
+
"transformers>=5.14.0",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
[tool.uv]
|
|
21
|
+
# mlx-optiq は transformers<5.13 を要求するが、mlx-vlm>=0.6.5 は 5.14+ が必要
|
|
22
|
+
override-dependencies = [
|
|
23
|
+
"transformers>=5.14.0",
|
|
17
24
|
]
|
|
18
25
|
|
|
19
26
|
[dependency-groups]
|
|
@@ -3,7 +3,7 @@ import json
|
|
|
3
3
|
import sys
|
|
4
4
|
|
|
5
5
|
from backends.base import ModelBackend
|
|
6
|
-
from handlers import handle_cache_prefill, handle_capabilities,
|
|
6
|
+
from handlers import handle_cache_prefill, handle_capabilities, handle_completion, handle_format_test, handle_generate, handle_render, handle_tokenize
|
|
7
7
|
from handlers.cancel import request_cancel, reset_cancel
|
|
8
8
|
|
|
9
9
|
|
|
@@ -27,6 +27,15 @@ def read():
|
|
|
27
27
|
continue
|
|
28
28
|
|
|
29
29
|
|
|
30
|
+
def _is_valid_generate_prompt(prompt) -> bool:
|
|
31
|
+
"""prompt は非空文字列または非空のトークン ID リスト"""
|
|
32
|
+
if isinstance(prompt, str):
|
|
33
|
+
return bool(prompt)
|
|
34
|
+
if isinstance(prompt, list):
|
|
35
|
+
return len(prompt) > 0
|
|
36
|
+
return False
|
|
37
|
+
|
|
38
|
+
|
|
30
39
|
class Server:
|
|
31
40
|
def __init__(self, backend: ModelBackend, capabilities: dict):
|
|
32
41
|
self.backend = backend
|
|
@@ -93,21 +102,32 @@ class Server:
|
|
|
93
102
|
reasoning_effort=req.get('reasoning_effort'),
|
|
94
103
|
)
|
|
95
104
|
|
|
96
|
-
elif method == '
|
|
105
|
+
elif method == 'render':
|
|
97
106
|
messages = req.get('messages')
|
|
98
107
|
if not messages:
|
|
99
|
-
self._error_response("'messages' field is required for
|
|
108
|
+
self._error_response("'messages' field is required for render method")
|
|
100
109
|
return
|
|
101
|
-
|
|
110
|
+
handle_render(
|
|
102
111
|
self.backend,
|
|
103
|
-
self.capabilities,
|
|
104
112
|
messages,
|
|
105
|
-
primer=req.get('primer'),
|
|
106
113
|
options=req.get('options', {}),
|
|
107
114
|
tools=req.get('tools'),
|
|
108
|
-
images=req.get('images', []),
|
|
109
|
-
max_image_size=req.get('maxImageSize', 768),
|
|
110
115
|
reasoning_effort=req.get('reasoning_effort'),
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
elif method == 'generate':
|
|
119
|
+
prompt = req.get('prompt')
|
|
120
|
+
if not _is_valid_generate_prompt(prompt):
|
|
121
|
+
self._error_response("'prompt' field is required for generate method")
|
|
122
|
+
return
|
|
123
|
+
images = req.get('images', [])
|
|
124
|
+
handle_generate(
|
|
125
|
+
self.backend,
|
|
126
|
+
prompt,
|
|
127
|
+
options=req.get('options', {}),
|
|
128
|
+
images=images if images else None,
|
|
129
|
+
max_image_size=req.get('maxImageSize', 768),
|
|
130
|
+
primer=req.get('primer'),
|
|
111
131
|
cache_path=req.get('cache_path'),
|
|
112
132
|
cache_trim_tokens=req.get('cache_trim_tokens'),
|
|
113
133
|
)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""apply_chat_template によるプロンプト整形(推論なし)"""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from utils.prompt_builder import supports_chat_template
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def apply_chat_template_prompt(
|
|
9
|
+
backend,
|
|
10
|
+
messages: list,
|
|
11
|
+
*,
|
|
12
|
+
primer: str | None = None,
|
|
13
|
+
tools: list | None = None,
|
|
14
|
+
reasoning_effort: str | None = None,
|
|
15
|
+
trust_remote_code: bool | None = None,
|
|
16
|
+
) -> str | list:
|
|
17
|
+
"""messages を chat template で整形して prompt を返す"""
|
|
18
|
+
tokenizer = backend.get_tokenizer()
|
|
19
|
+
|
|
20
|
+
if not supports_chat_template(tokenizer):
|
|
21
|
+
raise ValueError("chat_template_not_available")
|
|
22
|
+
|
|
23
|
+
add_generation_prompt = True
|
|
24
|
+
fmt_messages = list(messages)
|
|
25
|
+
if primer is not None:
|
|
26
|
+
fmt_messages.append({"role": "assistant", "content": primer})
|
|
27
|
+
add_generation_prompt = False
|
|
28
|
+
|
|
29
|
+
if backend.supports_vision():
|
|
30
|
+
try:
|
|
31
|
+
prompt = tokenizer.apply_chat_template(
|
|
32
|
+
fmt_messages,
|
|
33
|
+
tools=tools,
|
|
34
|
+
add_generation_prompt=add_generation_prompt,
|
|
35
|
+
tokenize=False,
|
|
36
|
+
)
|
|
37
|
+
except TypeError:
|
|
38
|
+
prompt = tokenizer.apply_chat_template(
|
|
39
|
+
fmt_messages,
|
|
40
|
+
add_generation_prompt=add_generation_prompt,
|
|
41
|
+
tokenize=False,
|
|
42
|
+
)
|
|
43
|
+
else:
|
|
44
|
+
extra_kwargs: dict = {}
|
|
45
|
+
if tools is not None:
|
|
46
|
+
extra_kwargs["tools"] = tools
|
|
47
|
+
if reasoning_effort is not None:
|
|
48
|
+
extra_kwargs["reasoning_effort"] = reasoning_effort
|
|
49
|
+
if trust_remote_code is not None:
|
|
50
|
+
extra_kwargs["trust_remote_code"] = trust_remote_code
|
|
51
|
+
|
|
52
|
+
try:
|
|
53
|
+
prompt = tokenizer.apply_chat_template(
|
|
54
|
+
fmt_messages,
|
|
55
|
+
add_generation_prompt=add_generation_prompt,
|
|
56
|
+
tokenize=False,
|
|
57
|
+
**extra_kwargs,
|
|
58
|
+
)
|
|
59
|
+
except TypeError:
|
|
60
|
+
try:
|
|
61
|
+
fallback_kwargs: dict = {}
|
|
62
|
+
if tools is not None:
|
|
63
|
+
fallback_kwargs["tools"] = tools
|
|
64
|
+
prompt = tokenizer.apply_chat_template(
|
|
65
|
+
fmt_messages,
|
|
66
|
+
add_generation_prompt=add_generation_prompt,
|
|
67
|
+
tokenize=False,
|
|
68
|
+
**fallback_kwargs,
|
|
69
|
+
)
|
|
70
|
+
except TypeError:
|
|
71
|
+
prompt = tokenizer.apply_chat_template(
|
|
72
|
+
fmt_messages,
|
|
73
|
+
add_generation_prompt=add_generation_prompt,
|
|
74
|
+
tokenize=False,
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
if primer is not None and isinstance(prompt, str):
|
|
78
|
+
prompt = primer.join(prompt.split(primer)[0:-1]) + primer
|
|
79
|
+
|
|
80
|
+
return prompt
|
|
@@ -342,11 +342,11 @@ def get_capabilities(tokenizer):
|
|
|
342
342
|
dict: capabilities情報
|
|
343
343
|
"""
|
|
344
344
|
# 基本メソッド
|
|
345
|
-
methods = ["capabilities", "completion", "format_test"]
|
|
345
|
+
methods = ["capabilities", "completion", "generate", "format_test"]
|
|
346
346
|
|
|
347
347
|
# apply_chat_templateがある場合はchatメソッドを追加
|
|
348
348
|
if hasattr(tokenizer, 'apply_chat_template'):
|
|
349
|
-
methods.append("
|
|
349
|
+
methods.append("render")
|
|
350
350
|
|
|
351
351
|
capabilities = {
|
|
352
352
|
"methods": methods,
|