From d29685275bf0f5852a777d7455ebee1ced92167b Mon Sep 17 00:00:00 2001 From: Classic298 <27028174+Classic298@users.noreply.github.com> Date: Mon, 27 Jul 2026 07:47:23 +0200 Subject: [PATCH] perf: drop the full-payload deepcopy in the OpenAI to Ollama conversion (#27371) convert_payload_openai_to_ollama deep-copied the entire request payload on every completion routed to an Ollama model, and again on every tool-call iteration. The cost of that copy scales with the number of messages and nested content parts in the history, so long chats pay the most, purely as CPU work before the request even leaves the server. The function only ever mutates two things: it deletes keys on the top-level dict and on the nested options dict. convert_messages_openai_to_ollama already builds fresh message dicts. Shallow-copying exactly those two levels therefore preserves behavior while removing the whole-tree copy. Benchmark (per conversion call): | payload | before | after | speedup | | --- | --- | --- | --- | | 200-message text chat (~180 KB) | 0.22 ms | 0.057 ms | 4x | | 20-message chat + 1 MB base64 image | 0.41 ms | 0.38 ms | 1.1x | The image row barely moves because deepcopy shares immutable strings; the win comes from container-heavy histories, which are exactly the payloads that grow over a conversation's lifetime. The output is byte-identical to the previous implementation (verified against it, including dict key order, root parameter hoisting, max_tokens remapping, stop handling and response_format precedence), and the caller's payload is left unmodified exactly as before. --- backend/open_webui/utils/payload.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/backend/open_webui/utils/payload.py b/backend/open_webui/utils/payload.py index 89568c3a63..e47e72b94f 100644 --- a/backend/open_webui/utils/payload.py +++ b/backend/open_webui/utils/payload.py @@ -1,4 +1,3 @@ -import copy import json from typing import Callable, Optional @@ -307,9 +306,10 @@ def convert_payload_openai_to_ollama(openai_payload: dict) -> dict: Returns: dict: A modified payload compatible with the Ollama API. """ - # Shallow copy metadata separately (may contain non-picklable objects) + # Only the top-level dict and the nested options dict are mutated below, so + # shallow copies suffice; deepcopy walked the entire message tree per call. metadata = openai_payload.get('metadata') - openai_payload = copy.deepcopy({k: v for k, v in openai_payload.items() if k != 'metadata'}) + openai_payload = {k: v for k, v in openai_payload.items() if k != 'metadata'} if metadata is not None: openai_payload['metadata'] = dict(metadata) ollama_payload = {} @@ -327,8 +327,9 @@ def convert_payload_openai_to_ollama(openai_payload: dict) -> dict: # If there are advanced parameters in the payload, format them in Ollama's options field if openai_payload.get('options'): - ollama_payload['options'] = openai_payload['options'] - ollama_options = openai_payload['options'] + # Copied before key deletions below so the caller's options stay intact + ollama_options = dict(openai_payload['options']) + ollama_payload['options'] = ollama_options def parse_json(value: str) -> dict: """