mirror of
https://github.com/ggml-org/llama.cpp.git
synced 2026-10-03 11:27:25 -05:00
Pre-processing
This commit is contained in:
@@ -1591,3 +1591,65 @@ mtmd_image_preproc_out mtmd_image_preprocessor_granite::preprocess(const clip_im
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
//
|
||||
// mtmd_image_preprocessor_onyx
|
||||
//
|
||||
|
||||
// Replicates transformers' get_aspect_ratio_preserving_size (image_processing_onyx.py)
|
||||
static clip_image_size onyx_grid_size(int img_w, int img_h, int patch_hw, int max_tokens) {
|
||||
double i_nph = (double) img_h / patch_hw;
|
||||
double i_npw = (double) img_w / patch_hw;
|
||||
const double ratio = i_nph > 0.0 ? i_npw / i_nph : 1.0;
|
||||
if (i_nph * i_npw > (double) max_tokens) {
|
||||
i_nph = std::sqrt((double) max_tokens / ratio);
|
||||
i_npw = i_nph * ratio;
|
||||
}
|
||||
const int hs[2] = { (int) std::floor(i_nph), (int) std::ceil(i_nph) };
|
||||
const int ws[2] = { (int) std::floor(i_npw), (int) std::ceil(i_npw) };
|
||||
const double target_ar = (double) img_h / (double) img_w;
|
||||
int best_nph = -1;
|
||||
int best_npw = -1;
|
||||
double best_d = 0.0;
|
||||
for (int a = 0; a < 2; ++a) {
|
||||
for (int b = 0; b < 2; ++b) {
|
||||
const int nph = hs[a];
|
||||
const int npw = ws[b];
|
||||
if (nph < 1 || npw < 1 || nph * npw > max_tokens) {
|
||||
continue;
|
||||
}
|
||||
const double d = std::fabs((double) nph / (double) npw - target_ar);
|
||||
const int n_tokens = nph * npw;
|
||||
const int best_n_tokens = best_nph * best_npw;
|
||||
if (best_nph < 0 || d < best_d || (d == best_d && n_tokens > best_n_tokens)) {
|
||||
best_nph = nph;
|
||||
best_npw = npw;
|
||||
best_d = d;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (best_nph < 0) { // no candidate fit under the cap: round and clamp
|
||||
best_nph = std::max(1, (int) std::lround(i_nph));
|
||||
best_npw = std::max(1, (int) std::lround(i_npw));
|
||||
}
|
||||
return clip_image_size{ best_npw * patch_hw, best_nph * patch_hw };
|
||||
}
|
||||
|
||||
mtmd_image_preproc_out mtmd_image_preprocessor_onyx::preprocess(const clip_image_u8 & img) {
|
||||
const int patch_hw = hparams.patch_size * hparams.n_merge;
|
||||
const int patch_area = hparams.patch_size * hparams.patch_size * hparams.n_merge * hparams.n_merge;
|
||||
GGML_ASSERT(patch_area > 0 && hparams.image_max_pixels > 0);
|
||||
const int max_tokens = hparams.image_max_pixels / patch_area;
|
||||
|
||||
const clip_image_size original_size = img.get_size();
|
||||
const clip_image_size target_size = onyx_grid_size(
|
||||
original_size.width, original_size.height, patch_hw, max_tokens);
|
||||
|
||||
// PIL resizes directly to (target_w, target_h) -- a stretch, no padding.
|
||||
clip_image_u8 resized_image;
|
||||
img_tool::resize(img, resized_image, target_size, hparams.image_resize_algo, PAD_NONE);
|
||||
|
||||
mtmd_image_preproc_out output;
|
||||
output.append(hparams, resized_image, true);
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -224,3 +224,9 @@ struct mtmd_image_preprocessor_granite : mtmd_image_preprocessor_llava_uhd {
|
||||
mtmd_image_preprocessor_granite(const clip_ctx * ctx) : mtmd_image_preprocessor_llava_uhd(ctx) {}
|
||||
mtmd_image_preproc_out preprocess(const clip_image_u8 & img) override;
|
||||
};
|
||||
|
||||
// pick the patch grid closest to the input aspect ratio under the per-image token cap, stretch-resize.
|
||||
struct mtmd_image_preprocessor_onyx : mtmd_image_preprocessor {
|
||||
mtmd_image_preprocessor_onyx(const clip_ctx * ctx) : mtmd_image_preprocessor(ctx) {}
|
||||
mtmd_image_preproc_out preprocess(const clip_image_u8 & img) override;
|
||||
};
|
||||
|
||||
@@ -470,6 +470,11 @@ struct mtmd_context {
|
||||
img_end = "]<]end of image[>[";
|
||||
image_preproc = std::make_unique<mtmd_image_preprocessor_dyn_size>(ctx_v);
|
||||
} break;
|
||||
case PROJECTOR_TYPE_ONYX:
|
||||
{
|
||||
// Follow transformers Onyx processing: <|patch|>*N, no delimiters
|
||||
image_preproc = std::make_unique<mtmd_image_preprocessor_onyx>(ctx_v);
|
||||
} break;
|
||||
case PROJECTOR_TYPE_YOUTUVL:
|
||||
{
|
||||
// <|vision_start|> ... (image embeddings) ... <|vision_end|>
|
||||
|
||||
Reference in New Issue
Block a user