diff --git a/bigframes/ml/llm.py b/bigframes/ml/llm.py index a2964a4fef..cce05ea1f2 100644 --- a/bigframes/ml/llm.py +++ b/bigframes/ml/llm.py @@ -103,6 +103,8 @@ "You should use this model name only if you are sure that it is supported in BigQuery." ) +_REMOVE_DEFAULT_MODEL_WARNING = "Since upgrading the default model can cause unintended breakages, the default model will be removed in BigFrames 3.0. Please supply an explicit model to avoid this message." + @log_adapter.class_logger class TextEmbeddingGenerator(base.RetriableRemotePredictor): @@ -113,7 +115,8 @@ class TextEmbeddingGenerator(base.RetriableRemotePredictor): The model for text embedding. Possible values are "text-embedding-005", "text-embedding-004" or "text-multilingual-embedding-002". text-embedding models returns model embeddings for text inputs. text-multilingual-embedding models returns model embeddings for text inputs which support over 100 languages. - Default to "text-embedding-004". + If no setting is provided, "text-embedding-004" will be used by + default and a warning will be issued. session (bigframes.Session or None): BQ session to create the model. If None, use the global default session. connection_name (str or None): @@ -124,14 +127,20 @@ class TextEmbeddingGenerator(base.RetriableRemotePredictor): def __init__( self, *, - model_name: Literal[ - "text-embedding-005", - "text-embedding-004", - "text-multilingual-embedding-002", - ] = "text-embedding-004", + model_name: Optional[ + Literal[ + "text-embedding-005", + "text-embedding-004", + "text-multilingual-embedding-002", + ] + ] = None, session: Optional[bigframes.Session] = None, connection_name: Optional[str] = None, ): + if model_name is None: + model_name = "text-embedding-004" + msg = exceptions.format_message(_REMOVE_DEFAULT_MODEL_WARNING) + warnings.warn(msg, category=FutureWarning, stacklevel=2) self.model_name = model_name self.session = session or global_session.get_global_session() self.connection_name = connection_name @@ -256,7 +265,8 @@ class MultimodalEmbeddingGenerator(base.RetriableRemotePredictor): Args: model_name (str, Default to "multimodalembedding@001"): The model for multimodal embedding. Can set to "multimodalembedding@001". Multimodal-embedding models returns model embeddings for text, image and video inputs. - Default to "multimodalembedding@001". + If no setting is provided, "multimodalembedding@001" will be used by + default and a warning will be issued. session (bigframes.Session or None): BQ session to create the model. If None, use the global default session. connection_name (str or None): @@ -267,12 +277,16 @@ class MultimodalEmbeddingGenerator(base.RetriableRemotePredictor): def __init__( self, *, - model_name: Literal["multimodalembedding@001"] = "multimodalembedding@001", + model_name: Optional[Literal["multimodalembedding@001"]] = None, session: Optional[bigframes.Session] = None, connection_name: Optional[str] = None, ): if not bigframes.options.experiments.blob: raise NotImplementedError() + if model_name is None: + model_name = "multimodalembedding@001" + msg = exceptions.format_message(_REMOVE_DEFAULT_MODEL_WARNING) + warnings.warn(msg, category=FutureWarning, stacklevel=2) self.model_name = model_name self.session = session or global_session.get_global_session() self.connection_name = connection_name @@ -408,7 +422,8 @@ class GeminiTextGenerator(base.RetriableRemotePredictor): "gemini-1.5-pro-001", "gemini-1.5-pro-002", "gemini-1.5-flash-001", "gemini-1.5-flash-002", "gemini-2.0-flash-exp", "gemini-2.0-flash-lite-001", and "gemini-2.0-flash-001". - Default to "gemini-2.0-flash-001". + If no setting is provided, "gemini-2.0-flash-001" will be used by + default and a warning will be issued. .. note:: "gemini-2.0-flash-exp", "gemini-1.5-pro-preview-0514" and "gemini-1.5-flash-preview-0514" is subject to the "Pre-GA Offerings Terms" in the General Service Terms section of the @@ -429,17 +444,19 @@ class GeminiTextGenerator(base.RetriableRemotePredictor): def __init__( self, *, - model_name: Literal[ - "gemini-1.5-pro-preview-0514", - "gemini-1.5-flash-preview-0514", - "gemini-1.5-pro-001", - "gemini-1.5-pro-002", - "gemini-1.5-flash-001", - "gemini-1.5-flash-002", - "gemini-2.0-flash-exp", - "gemini-2.0-flash-001", - "gemini-2.0-flash-lite-001", - ] = "gemini-2.0-flash-001", + model_name: Optional[ + Literal[ + "gemini-1.5-pro-preview-0514", + "gemini-1.5-flash-preview-0514", + "gemini-1.5-pro-001", + "gemini-1.5-pro-002", + "gemini-1.5-flash-001", + "gemini-1.5-flash-002", + "gemini-2.0-flash-exp", + "gemini-2.0-flash-001", + "gemini-2.0-flash-lite-001", + ] + ] = None, session: Optional[bigframes.Session] = None, connection_name: Optional[str] = None, max_iterations: int = 300, @@ -454,6 +471,10 @@ def __init__( "(https://cloud.google.com/products#product-launch-stages)." ) warnings.warn(msg, category=exceptions.PreviewWarning) + if model_name is None: + model_name = "gemini-2.0-flash-001" + msg = exceptions.format_message(_REMOVE_DEFAULT_MODEL_WARNING) + warnings.warn(msg, category=FutureWarning, stacklevel=2) self.model_name = model_name self.session = session or global_session.get_global_session() self.max_iterations = max_iterations @@ -803,7 +824,8 @@ class Claude3TextGenerator(base.RetriableRemotePredictor): "claude-3-5-sonnet" is Anthropic's most powerful AI model and maintains the speed and cost of Claude 3 Sonnet, which is a mid-tier model. "claude-3-opus" is Anthropic's second-most powerful AI model, with strong performance on highly complex tasks. https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-claude#available-claude-models - Default to "claude-3-sonnet". + If no setting is provided, "claude-3-sonnet" will be used by default + and a warning will be issued. session (bigframes.Session or None): BQ session to create the model. If None, use the global default session. connection_name (str or None): @@ -815,12 +837,21 @@ class Claude3TextGenerator(base.RetriableRemotePredictor): def __init__( self, *, - model_name: Literal[ - "claude-3-sonnet", "claude-3-haiku", "claude-3-5-sonnet", "claude-3-opus" - ] = "claude-3-sonnet", + model_name: Optional[ + Literal[ + "claude-3-sonnet", + "claude-3-haiku", + "claude-3-5-sonnet", + "claude-3-opus", + ] + ] = None, session: Optional[bigframes.Session] = None, connection_name: Optional[str] = None, ): + if model_name is None: + model_name = "claude-3-sonnet" + msg = exceptions.format_message(_REMOVE_DEFAULT_MODEL_WARNING) + warnings.warn(msg, category=FutureWarning, stacklevel=2) self.model_name = model_name self.session = session or global_session.get_global_session() self.connection_name = connection_name diff --git a/tests/system/small/ml/test_llm.py b/tests/system/small/ml/test_llm.py index ce314223c8..544889bf5a 100644 --- a/tests/system/small/ml/test_llm.py +++ b/tests/system/small/ml/test_llm.py @@ -762,3 +762,19 @@ def test_llm_gemini_pro_score_params(llm_fine_tune_df_default_index, model_name) def test_gemini_preview_model_warnings(model_name): with pytest.warns(exceptions.PreviewWarning): llm.GeminiTextGenerator(model_name=model_name) + + +@pytest.mark.parametrize( + "model_class", + [ + llm.TextEmbeddingGenerator, + llm.MultimodalEmbeddingGenerator, + llm.GeminiTextGenerator, + llm.Claude3TextGenerator, + ], +) +def test_text_embedding_generator_no_default_model_warning(model_class): + message = "Since upgrading the default model can cause unintended breakages, the\ndefault model will be removed in BigFrames 3.0. Please supply an\nexplicit model to avoid this message." + bigframes.options.experiments.blob = True + with pytest.warns(FutureWarning, match=message): + model_class(model_name=None)