mirror of
https://github.com/tiennm99/litellm.git
synced 2026-07-15 04:32:22 +00:00
fix: resolve memory leak caused by Pydantic 2.11+ deprecation warnings (#16110)
- Access model_fields on class instead of instance to avoid deprecation warnings - Add warning filter to suppress Pydantic instance attribute access warnings - Fix affects streaming operations where warnings accumulate over time - Updated cost_calculator.py, core_helpers.py, and model_response_utils.py The previous implementation accessed model_fields on Pydantic model instances, which triggers deprecation warnings in Pydantic 2.11+. These warnings accumulate during streaming operations, causing memory leaks. Now accessing model_fields via type(instance).model_fields to prevent warning generation.
This commit is contained in:
@@ -2,6 +2,9 @@
|
||||
import warnings
|
||||
|
||||
warnings.filterwarnings("ignore", message=".*conflict with protected namespace.*")
|
||||
# Suppress Pydantic 2.11+ deprecation warning about accessing model_fields on instances
|
||||
# This warning can accumulate during streaming and cause memory leaks
|
||||
warnings.filterwarnings("ignore", message=".*Accessing the.*attribute on the instance is deprecated.*")
|
||||
### INIT VARIABLES ######################
|
||||
import threading
|
||||
import os
|
||||
|
||||
@@ -1595,7 +1595,8 @@ class BaseTokenUsageProcessor:
|
||||
combined.prompt_tokens_details = PromptTokensDetailsWrapper()
|
||||
|
||||
# Check what keys exist in the model's prompt_tokens_details
|
||||
for attr in usage.prompt_tokens_details.model_fields:
|
||||
# Access model_fields on the class, not the instance, to avoid Pydantic 2.11+ deprecation warnings
|
||||
for attr in type(usage.prompt_tokens_details).model_fields:
|
||||
if (
|
||||
hasattr(usage.prompt_tokens_details, attr)
|
||||
and not attr.startswith("_")
|
||||
@@ -1626,7 +1627,8 @@ class BaseTokenUsageProcessor:
|
||||
)
|
||||
|
||||
# Check what keys exist in the model's completion_tokens_details
|
||||
for attr in usage.completion_tokens_details.model_fields:
|
||||
# Access model_fields on the class, not the instance, to avoid Pydantic 2.11+ deprecation warnings
|
||||
for attr in type(usage.completion_tokens_details).model_fields:
|
||||
if not attr.startswith("_") and not callable(
|
||||
getattr(usage.completion_tokens_details, attr)
|
||||
):
|
||||
|
||||
@@ -234,7 +234,8 @@ def preserve_upstream_non_openai_attributes(
|
||||
"""
|
||||
Preserve non-OpenAI attributes from the original chunk.
|
||||
"""
|
||||
expected_keys = set(model_response.model_fields.keys()).union({"usage"})
|
||||
# Access model_fields on the class, not the instance, to avoid Pydantic 2.11+ deprecation warnings
|
||||
expected_keys = set(type(model_response).model_fields.keys()).union({"usage"})
|
||||
for key, value in original_chunk.model_dump().items():
|
||||
if key not in expected_keys:
|
||||
setattr(model_response, key, value)
|
||||
|
||||
@@ -46,7 +46,8 @@ def is_model_response_stream_empty(model_response: ModelResponseStream) -> bool:
|
||||
return False
|
||||
|
||||
# Check for any non-base fields that are set
|
||||
for model_response_field in model_response.model_fields.keys():
|
||||
# Access model_fields on the class, not the instance, to avoid Pydantic 2.11+ deprecation warnings
|
||||
for model_response_field in type(model_response).model_fields.keys():
|
||||
# Skip base fields that are always set
|
||||
if model_response_field in BASE_FIELDS:
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user