Compare commits

...
15 changed files with 276 additions and 29 deletions
+1 -1
View File
@@ -139,7 +139,7 @@ void example_log_printf(sd_log_level_t level, const char* file, int line, const
while (!message.empty() && (message.back() == '\n' || message.back() == '\r')) {
message.pop_back();
}
message += " - " + sd_basename(file) + ":" + std::to_string(line) + '\n';
message += " --- " + sd_basename(file) + ":" + std::to_string(line) + '\n';
log_print(level, message.c_str(), log_level, log_color);
}
+37 -1
View File
@@ -37,6 +37,7 @@ Current generation-related endpoints include:
- `POST /sdapi/v1/txt2img`
- `POST /sdapi/v1/img2img`
- `GET /sdapi/v1/progress`
- `GET /sdapi/v1/loras`
- `GET /sdapi/v1/upscalers`
- `GET /sdapi/v1/latent-upscale-modes`
@@ -278,6 +279,26 @@ Response fields:
| `parameters` | `object` | Echo of the parsed outer request body |
| `info` | `string` | Currently empty string |
#### `GET /sdapi/v1/progress`
Poll this endpoint while a synchronous SDAPI generation request is running.
An optional `id_task` query parameter selects the task with the same `id_task`
provided in the generation request (default: `"sdapi"`). Set
`skip_current_image=true` or `1` to omit the preview image.
`current_image` contains the latest base64 JPEG latent projection, or `null`
when unavailable. `state.sampling_step` is the positive logical step and
`state.sampling_steps` is the actual step count for the current sampling pass,
including schedule and img2img strength adjustments. `state.job_no` is the
zero-based pass index; `state.job_count` includes one pass per batch image and
an additional pass per image when highres fix is enabled. `progress` weights
these passes equally. Sampling progress can reach `1` before final decoding
finishes; `eta_relative` is currently always `0`.
When no SDAPI task is active, or `id_task` does not match, the endpoint returns
`progress=0`, `state.job=""`, zero job/step counts, and `current_image=null`.
Completed and failed requests do not retain an active preview.
#### Discovery / Compatibility Endpoints
Currently exposed:
@@ -1074,7 +1095,8 @@ Response fields:
Compared with `img_gen`, the `vid_gen` request body:
- `vid_gen` is a single video sequence job, so `batch_count` is not part of the request schema
- `ref_images`, `mask_image`, `control_image`, `control_strength`, `ip_adapter_image`, `ip_adapter_strength`, and `embed_image_metadata` are not part of the request schema
- `mask_image`, `control_image`, `control_strength`, `ip_adapter_image`, `ip_adapter_strength`, and `embed_image_metadata` are not part of the request schema
- `ref_images` is accepted for MiniMax-H3 Ref2VA conditioning; other video model families currently ignore it
- `vid_gen` adds `end_image`, `control_frames`, `high_noise_sample_params`, `video_frames`, `fps`, `moe_boundary`, and `vace_strength`
Example:
@@ -1095,6 +1117,7 @@ Example:
"init_image": null,
"end_image": null,
"ref_images": [],
"control_frames": [],
"sample_params": {
@@ -1164,6 +1187,17 @@ Example:
}
```
### Reference Image Rules
- `ref_images` contains reference images for MiniMax-H3 Ref2VA conditioning.
- Images retain request order and correspond to `<Picture 1>`, `<Picture 2>`, and so on in the prompt.
- For MiniMax-H3, non-empty `ref_images` cannot be combined with `init_image` or `end_image`. A conflicting API request fails during generation; the WebUI checks this before submission.
- MiniMax-H3 does not support `control_frames`; leave that array empty.
- Other video model families currently ignore `ref_images`.
- `features_by_mode.vid_gen` does not currently advertise `ref_images`; its absence is not an indication that MiniMax-H3 reference images are unsupported.
See [MiniMax-H3 reference conditioning](../../docs/minimax_h3.md#reference-to-audio-video-conditioning) for model requirements and prompt examples.
### LoRA Rules
- The server only accepts explicit LoRA entries from the `lora` field.
@@ -1181,6 +1215,7 @@ Channel expectations:
- `init_image`: 3 channels
- `end_image`: 3 channels
- `ref_images[]`: decoded with native channels, then converted to RGB by MiniMax-H3
- `control_frames[]`: 3 channels
Frame ordering rules:
@@ -1219,6 +1254,7 @@ Image and frame fields:
| --- | --- |
| `init_image` | `string \| null` |
| `end_image` | `string \| null` |
| `ref_images` | `array<string>` |
| `control_frames` | `array<string>` |
LoRA fields:
+2
View File
@@ -75,6 +75,8 @@ int main(int argc, const char** argv) {
}
SDSvrParams svr_params;
SDContextParams ctx_params;
// Preserve the CLI default while disabling cwd scans for sd-server.
ctx_params.lora_model_dir.clear();
SDGenerationParams default_gen_params;
sd_set_log_callback(sd_log_cb, (void*)&svr_params);
+132 -1
View File
@@ -301,6 +301,76 @@ static nlohmann::json prepare_info_field(const SDContextParams& ctx_params,
return jsoninfo;
}
struct SDAPIPreviewState {
std::mutex mutex;
std::string b64;
std::string id_task;
std::string job_type;
int step = 0;
int total = 0;
bool active = false;
int64_t job_count = 0;
int job_no = 0;
};
static SDAPIPreviewState g_preview;
static void preview_callback(int step, int frame_count, sd_image_t* frames, bool is_noisy, void* data) {
(void)is_noisy;
(void)data;
if (frame_count <= 0 || frames == nullptr || frames[0].data == nullptr) {
return;
}
const sd_image_t& frame = frames[0];
const sd_preview_info_t info = sd_get_preview_info();
auto image_bytes = encode_image_to_vector(EncodedImageFormat::JPEG,
frame.data,
frame.width,
frame.height,
frame.channel,
"",
80);
if (image_bytes.empty()) {
return;
}
std::string b64 = base64_encode(image_bytes);
std::lock_guard<std::mutex> lock(g_preview.mutex);
g_preview.b64 = std::move(b64);
g_preview.step = static_cast<int>(std::min<int64_t>(step < 0 ? -static_cast<int64_t>(step) : step,
std::max(0, info.total_steps)));
g_preview.total = std::max(0, info.total_steps);
g_preview.job_no = std::max(0, info.sample_pass - 1);
}
struct SDAPIPreviewGuard {
SDAPIPreviewGuard(const std::string& id_task, const sd_img_gen_params_t& params, const std::string& job_type) {
std::lock_guard<std::mutex> lock(g_preview.mutex);
g_preview.id_task = id_task;
g_preview.total = 0;
g_preview.job_type = job_type;
g_preview.b64.clear();
g_preview.step = 0;
g_preview.active = true;
// Each batch item has a base pass and, when enabled, a hires pass.
g_preview.job_count = static_cast<int64_t>(std::max(1, params.batch_count)) * (params.hires.enabled ? 2 : 1);
g_preview.job_no = 0;
sd_set_preview_callback(preview_callback, PREVIEW_PROJ, 1, true, false, nullptr);
}
~SDAPIPreviewGuard() {
sd_set_preview_callback(nullptr, PREVIEW_NONE, 1, false, false, nullptr);
std::lock_guard<std::mutex> lock(g_preview.mutex);
g_preview.active = false;
g_preview.b64.clear();
}
SDAPIPreviewGuard(const SDAPIPreviewGuard&) = delete;
SDAPIPreviewGuard& operator=(const SDAPIPreviewGuard&) = delete;
};
void register_sdapi_endpoints(httplib::Server& svr, ServerRuntime& rt) {
ServerRuntime* runtime = &rt;
@@ -317,7 +387,9 @@ void register_sdapi_endpoints(httplib::Server& svr, ServerRuntime& rt) {
return;
}
json j = json::parse(req.body);
std::string id_task = "sdapi";
json j = json::parse(req.body);
id_task = j.value("id_task", id_task);
ImgGenJobRequest request;
std::string error_message;
if (!build_sdapi_img_gen_request(j, *runtime, img2img, request, error_message)) {
@@ -334,6 +406,7 @@ void register_sdapi_endpoints(httplib::Server& svr, ServerRuntime& rt) {
{
std::lock_guard<std::mutex> lock(*runtime->sd_ctx_mutex);
SDAPIPreviewGuard preview_guard(id_task, img_gen_params, img2img ? "img2img" : "txt2img");
sd_image_t* raw_results = nullptr;
if (!generate_image(runtime->sd_ctx, &img_gen_params, &raw_results, &num_results)) {
raw_results = nullptr;
@@ -528,4 +601,62 @@ void register_sdapi_endpoints(httplib::Server& svr, ServerRuntime& rt) {
r["sd_model_checkpoint"] = model_path.stem();
res.set_content(r.dump(), "application/json");
});
svr.Get("/sdapi/v1/progress", [](const httplib::Request& req, httplib::Response& res) {
bool skip_current_image = false;
bool has_id_param = req.has_param("id_task");
std::string req_id_task = has_id_param ? req.get_param_value("id_task") : "";
if (req.has_param("skip_current_image")) {
std::string skip_str = req.get_param_value("skip_current_image");
skip_current_image = (skip_str == "true" || skip_str == "1");
}
json r;
r["eta_relative"] = 0.0f;
json state;
state["skipped"] = false;
state["interrupted"] = false;
state["job_timestamp"] = "0";
r["textinfo"] = nullptr;
{
std::lock_guard<std::mutex> lock(g_preview.mutex);
bool is_matching_task = g_preview.active && (!has_id_param || req_id_task == g_preview.id_task);
int step = is_matching_task ? g_preview.step : 0;
int steps = is_matching_task ? g_preview.total : 0;
std::string b64 = is_matching_task ? g_preview.b64 : "";
std::string job_type = is_matching_task ? g_preview.job_type : "";
int64_t job_count = is_matching_task ? g_preview.job_count : 0;
int job_no = is_matching_task ? g_preview.job_no : 0;
float batch_progress = (steps > 0) ? (static_cast<float>(step) / static_cast<float>(steps)) : 0.0f;
if (batch_progress > 1.0f)
batch_progress = 1.0f;
float overall_progress = job_count > 0
? (static_cast<float>(job_no) + batch_progress) / static_cast<float>(job_count)
: 0.0f;
if (overall_progress > 1.0f)
overall_progress = 1.0f;
r["progress"] = overall_progress;
state["job"] = job_type;
state["sampling_step"] = step;
state["sampling_steps"] = steps;
state["job_count"] = job_count;
state["job_no"] = job_no;
r["state"] = state;
if (!skip_current_image && !b64.empty()) {
r["current_image"] = b64;
} else {
r["current_image"] = nullptr;
}
}
res.set_content(r.dump(), "application/json");
});
}
+6
View File
@@ -254,6 +254,12 @@ std::string SDSvrParams::to_string() const {
void refresh_lora_cache(ServerRuntime& rt) {
std::vector<LoraEntry> new_cache;
if (rt.ctx_params->lora_model_dir.empty()) {
std::lock_guard<std::mutex> lock(*rt.lora_mutex);
rt.lora_cache->clear();
return;
}
fs::path lora_dir = rt.ctx_params->lora_model_dir;
std::error_code ec;
if (fs::exists(lora_dir, ec) && !ec && fs::is_directory(lora_dir, ec) && !ec) {
+31 -6
View File
@@ -399,7 +399,7 @@ struct FrozenCLIPEmbedderWithCustomWords : public Conditioner {
ss << "['" << item.first << "', " << item.second << "], ";
}
ss << "]";
LOG_VERBOSE("parse '%s' to %s", text.c_str(), ss.str().c_str());
LOG_VERBOSE("parse '%s' to %s", escape_newlines(text).c_str(), escape_newlines(ss.str()).c_str());
}
auto on_new_token_cb = [&](std::string& str, std::vector<int32_t>& bpe_tokens) -> bool {
@@ -817,7 +817,7 @@ struct SD3CLIPEmbedder : public Conditioner {
ss << "['" << item.first << "', " << item.second << "], ";
}
ss << "]";
LOG_VERBOSE("parse '%s' to %s", text.c_str(), ss.str().c_str());
LOG_VERBOSE("parse '%s' to %s", escape_newlines(text).c_str(), escape_newlines(ss.str()).c_str());
}
auto on_new_token_cb = [&](std::string& str, std::vector<int32_t>& bpe_tokens) -> bool {
@@ -909,6 +909,31 @@ struct SD3CLIPEmbedder : public Conditioner {
size_t chunk_count = std::max(std::max(clip_l_tokens.size(), clip_g_tokens.size()), t5_tokens.size()) / chunk_len;
// Each active encoder must cover every chunk of the longest token sequence.
Tokenizer* tokenizers[] = {
clip_l ? clip_l_tokenizer.get() : nullptr,
clip_g ? clip_g_tokenizer.get() : nullptr,
t5 ? &t5_tokenizer : nullptr,
};
const size_t target_length = chunk_count * chunk_len;
for (size_t encoder_idx = 0; encoder_idx < 3; encoder_idx++) {
auto& tokens = token_and_weights[encoder_idx].first;
auto& weights = token_and_weights[encoder_idx].second;
if (!tokenizers[encoder_idx] || tokens.size() >= target_length) {
continue;
}
std::vector<int> empty_tokens;
std::vector<float> empty_weights;
tokenizers[encoder_idx]->pad_tokens(empty_tokens, &empty_weights, nullptr, chunk_len, chunk_len, false);
while (tokens.size() < target_length) {
tokens.insert(tokens.end(), empty_tokens.begin(), empty_tokens.end());
weights.insert(weights.end(), empty_weights.begin(), empty_weights.end());
}
}
for (int chunk_idx = 0; chunk_idx < chunk_count; chunk_idx++) {
// clip_l
sd::Tensor<float> chunk_hidden_states_l;
@@ -1207,7 +1232,7 @@ struct FluxCLIPEmbedder : public Conditioner {
ss << "['" << item.first << "', " << item.second << "], ";
}
ss << "]";
LOG_VERBOSE("parse '%s' to %s", text.c_str(), ss.str().c_str());
LOG_VERBOSE("parse '%s' to %s", escape_newlines(text).c_str(), escape_newlines(ss.str()).c_str());
}
auto on_new_token_cb = [&](std::string& str, std::vector<int32_t>& bpe_tokens) -> bool {
@@ -1484,7 +1509,7 @@ struct T5CLIPEmbedder : public Conditioner {
ss << "['" << item.first << "', " << item.second << "], ";
}
ss << "]";
LOG_VERBOSE("parse '%s' to %s", text.c_str(), ss.str().c_str());
LOG_VERBOSE("parse '%s' to %s", escape_newlines(text).c_str(), escape_newlines(ss.str()).c_str());
}
auto on_new_token_cb = [&](std::string& str, std::vector<int32_t>& bpe_tokens) -> bool {
@@ -1873,7 +1898,7 @@ struct AnimaConditioner : public Conditioner {
ss << "['" << item.first << "', " << item.second << "], ";
}
ss << "]";
LOG_VERBOSE("parse '%s' to %s", text.c_str(), ss.str().c_str());
LOG_VERBOSE("parse '%s' to %s", escape_newlines(text).c_str(), escape_newlines(ss.str()).c_str());
}
std::vector<int> qwen_tokens;
@@ -2144,7 +2169,7 @@ struct LLMEmbedder : public Conditioner {
ss << "['" << item.first << "', " << item.second << "], ";
}
ss << "]";
LOG_VERBOSE("parse '%s' to %s", text.c_str(), ss.str().c_str());
LOG_VERBOSE("parse '%s' to %s", escape_newlines(text).c_str(), escape_newlines(ss.str()).c_str());
}
std::vector<int> tokens;
+11 -11
View File
@@ -223,13 +223,13 @@ ggml_tensor* ggml_ext_linear(ggml_context* ctx,
x = ggml_reshape_2d(ctx, x, x->ne[0], x->ne[1] * x->ne[2] * x->ne[3]);
x = ggml_mul_mat(ctx, w, x);
if (force_prec_f32) {
ggml_mul_mat_set_prec(x, GGML_PREC_F32);
ggml_prec_set_acc(x, GGML_PREC_F32);
}
x = ggml_reshape_4d(ctx, x, x->ne[0], x->ne[1] / ne2 / ne3, ne2, ne3);
} else {
x = ggml_mul_mat(ctx, w, x);
if (force_prec_f32) {
ggml_mul_mat_set_prec(x, GGML_PREC_F32);
ggml_prec_set_acc(x, GGML_PREC_F32);
}
}
if (scale != 1.f) {
@@ -488,7 +488,7 @@ ggml_tensor* ggml_ext_conv_3d(ggml_context* ctx,
x = ggml_mul_mat(ctx,
ggml_reshape_2d(ctx, im2col, im2col->ne[0], im2col->ne[3] * im2col->ne[2] * im2col->ne[1]),
ggml_reshape_2d(ctx, w, w->ne[0] * w->ne[1] * w->ne[2] * IC, OC));
ggml_mul_mat_set_prec(x, GGML_PREC_F32);
ggml_prec_set_acc(x, GGML_PREC_F32);
int64_t OD = im2col->ne[3] / N;
x = ggml_reshape_4d(ctx, x, im2col->ne[1] * im2col->ne[2], OD, N, OC);
@@ -683,8 +683,8 @@ ggml_tensor* ggml_ext_attention_ext(ggml_context* ctx,
v_in->type == GGML_TYPE_F32 && sd_backend_supports_cuda_mma(backend);
if (pad_head) {
// CUDA FA MMA starts at 64 channels; keep the original head's attention scale.
q_in = ggml_pad(ctx, q_in, 64 - d_head, 0, 0, 0);
k_in = ggml_pad(ctx, k_in, 64 - d_head, 0, 0, 0);
q_in = ggml_pad(ctx, q_in, static_cast<int>(64 - d_head), 0, 0, 0);
k_in = ggml_pad(ctx, k_in, static_cast<int>(64 - d_head), 0, 0, 0);
}
if (kv_scale != 1.0f) {
k_in = ggml_ext_scale(ctx, k_in, kv_scale);
@@ -694,7 +694,7 @@ ggml_tensor* ggml_ext_attention_ext(ggml_context* ctx,
v_in = ggml_ext_cont(ctx, ggml_permute(ctx, v_in, 0, 2, 1, 3));
v_in = ggml_reshape_3d(ctx, v_in, d_head, L_k, n_kv_head * N);
if (pad_head) {
v_in = ggml_pad(ctx, v_in, 64 - d_head, 0, 0, 0);
v_in = ggml_pad(ctx, v_in, static_cast<int>(64 - d_head), 0, 0, 0);
}
if (kv_scale != 1.0f) {
v_in = ggml_ext_scale(ctx, v_in, kv_scale);
@@ -721,7 +721,7 @@ ggml_tensor* ggml_ext_attention_ext(ggml_context* ctx,
if (!ggml_backend_supports_op(backend, out)) {
return nullptr;
}
ggml_flash_attn_ext_set_prec(out, GGML_PREC_F32);
ggml_prec_set_acc(out, GGML_PREC_F32);
if (kv_scale != 1.0f) {
out = ggml_ext_scale(ctx, out, 1.0f / kv_scale);
}
@@ -742,9 +742,9 @@ ggml_tensor* ggml_ext_attention_ext(ggml_context* ctx,
}
if (padded_head != d_head) {
// Keep the original head's softmax scale when padding for the CUDA kernel.
q_in = ggml_pad(ctx, q_in, padded_head - d_head, 0, 0, 0);
k_in = ggml_pad(ctx, k_in, padded_head - d_head, 0, 0, 0);
v_in = ggml_pad(ctx, v_in, padded_head - d_head, 0, 0, 0);
q_in = ggml_pad(ctx, q_in, static_cast<int>(padded_head - d_head), 0, 0, 0);
k_in = ggml_pad(ctx, k_in, static_cast<int>(padded_head - d_head), 0, 0, 0);
v_in = ggml_pad(ctx, v_in, static_cast<int>(padded_head - d_head), 0, 0, 0);
}
if (kv_scale != 1.0f) {
k_in = ggml_ext_scale(ctx, k_in, kv_scale);
@@ -797,7 +797,7 @@ ggml_tensor* ggml_ext_attention_ext(ggml_context* ctx,
v = ggml_reshape_3d(ctx, v, L_k, d_head, n_kv_head * N); // [N * n_kv_head, d_head, L_k]
auto kq = ggml_mul_mat(ctx, k, q); // [N * n_head, L_q, L_k]
ggml_mul_mat_set_prec(kq, GGML_PREC_F32);
ggml_prec_set_acc(kq, GGML_PREC_F32);
kq = ggml_scale_inplace(ctx, kq, scale);
if (mask) {
kq = ggml_add_inplace(ctx, kq, mask);
+16 -1
View File
@@ -62,6 +62,21 @@ void replace_all_chars(std::string& str, char target, char replacement) {
}
}
std::string escape_newlines(const std::string& text) {
std::string escaped;
escaped.reserve(text.size());
for (char ch : text) {
if (ch == '\n') {
escaped += "\\n";
} else if (ch == '\r') {
escaped += "\\r";
} else {
escaped += ch;
}
}
return escaped;
}
static std::string sd_vformat(const char* fmt, va_list ap) {
char small[128];
va_list ap2;
@@ -652,7 +667,7 @@ static void sd_log_dispatch(sd_log_level_t level, const std::string& origin, con
if (origin == "ggml") {
message = origin + ": " + message + '\n';
} else {
message += " - " + origin + '\n';
message += " --- " + origin + '\n';
}
sd_log_cb(level, message.c_str(), sd_log_cb_data);
}
+1
View File
@@ -29,6 +29,7 @@ bool contains(const std::string& str, const std::string& substr);
std::string sd_format(const char* fmt, ...);
void replace_all_chars(std::string& str, char target, char replacement);
std::string escape_newlines(const std::string& text);
int round_up_to(int value, int base);
+9 -2
View File
@@ -633,8 +633,11 @@ namespace MiniMaxH3VAE {
auto plan = make_vae_temporal_tile_plan(input.shape()[2], {17, 0});
auto result = process_vae_temporal_tiles(input, plan, [&](const sd::Tensor<float>& chunk, const VAETemporalTile& tile) {
SD_UNUSED(tile);
return VAE::encode(n_threads, chunk, tiling, circular_x, circular_y);
// keep the runner alive across chunks; ending it here would
// evict and reload the encoder weights every chunk
return VAE::encode(n_threads, chunk, tiling, circular_x, circular_y, false);
});
runner_end();
if (result.empty()) {
return {};
}
@@ -695,13 +698,16 @@ namespace MiniMaxH3VAE {
{static_cast<int>(tokens_per_chunk + token_overlap), static_cast<int>(token_overlap)});
GGML_ASSERT(plan.tiles.size() == static_cast<size_t>(num_chunks));
auto result = process_vae_temporal_tiles(input, plan, [&](const sd::Tensor<float>& chunk, const VAETemporalTile& tile) {
// keep the runner alive across chunks; ending it here would
// evict and reload the decoder weights every chunk
auto decoded = VAE::decode(n_threads,
chunk,
tiling,
true,
circular_x,
circular_y,
silent);
silent,
false);
if (decoded.empty()) {
return sd::Tensor<float>();
}
@@ -728,6 +734,7 @@ namespace MiniMaxH3VAE {
}
return first;
});
runner_end();
if (result.empty()) {
return {};
}
+26 -2
View File
@@ -241,6 +241,15 @@ public:
sd_tiling_params_t tiling_params,
bool circular_x = false,
bool circular_y = false) {
return encode(n_threads, x, tiling_params, circular_x, circular_y, true);
}
sd::Tensor<float> encode(int n_threads,
const sd::Tensor<float>& x,
sd_tiling_params_t tiling_params,
bool circular_x,
bool circular_y,
bool auto_end) {
int64_t t0 = ggml_time_ms();
tiling_params = resolve_tiling_params(tiling_params);
sd::Tensor<float> input = x;
@@ -280,7 +289,9 @@ public:
tiling_params);
}
runner_end();
if (auto_end) {
runner_end();
}
if (output.empty()) {
LOG_ERROR("vae encode compute failed");
@@ -298,6 +309,17 @@ public:
bool circular_x = false,
bool circular_y = false,
bool silent = false) {
return decode(n_threads, x, tiling_params, decode_video, circular_x, circular_y, silent, true);
}
sd::Tensor<float> decode(int n_threads,
const sd::Tensor<float>& x,
sd_tiling_params_t tiling_params,
bool decode_video,
bool circular_x,
bool circular_y,
bool silent,
bool auto_end) {
int64_t t0 = ggml_time_ms();
tiling_params = resolve_tiling_params(tiling_params);
sd::Tensor<float> input = x;
@@ -338,7 +360,9 @@ public:
tiling_params);
}
runner_end();
if (auto_end) {
runner_end();
}
if (output.empty()) {
LOG_ERROR("vae decode compute failed");
+1 -1
View File
@@ -242,7 +242,7 @@ bool BPETokenizer::encode(const std::string& text, std::vector<int>& result, on_
ss << "\"" << token << "\", ";
}
ss << "]";
LOG_VERBOSE("split prompt \"%s\" to %zu tokens %s", text.c_str(), bpe_tokens.size(), ss.str().c_str());
LOG_VERBOSE("split prompt \"%s\" to %zu tokens %s", escape_newlines(text).c_str(), bpe_tokens.size(), escape_newlines(ss.str()).c_str());
result = std::move(bpe_tokens);
return true;
}
+1 -1
View File
@@ -735,7 +735,7 @@ bool HFTokenizer::encode(const std::string& text, std::vector<int>& tokens, on_n
}
}
ss << "]";
LOG_VERBOSE("split prompt \"%s\" to %zu tokens %s", text.c_str(), result.size(), ss.str().c_str());
LOG_VERBOSE("split prompt \"%s\" to %zu tokens %s", escape_newlines(text).c_str(), result.size(), escape_newlines(ss.str()).c_str());
tokens = std::move(result);
return true;
}
+1 -1
View File
@@ -343,7 +343,7 @@ bool T5UniGramTokenizer::encode(const std::string& input, std::vector<int>& resu
ss << "\"" << token_str << "\", ";
}
ss << "]";
LOG_VERBOSE("split prompt \"%s\" to tokens %s", input.c_str(), ss.str().c_str());
LOG_VERBOSE("split prompt \"%s\" to tokens %s", escape_newlines(input).c_str(), escape_newlines(ss.str()).c_str());
result = std::move(tokens);
return true;