Skip to content

Conversation

@NickyJhames
Copy link
Contributor

@NickyJhames NickyJhames commented Sep 3, 2025

MLflow 3.1.0 Models-from-Code Migration for Question Answering with BERT Blueprint

DONT MERGE!!!!

Overview

Successfully migrated the Question Answering with BERT blueprint from MLflow's legacy serialization-based model logging (python_model) to the modern models-from-code approach (loader_module + data_path). This comprehensive architectural refactoring resolves critical MLflow 3.1.0 compatibility issues, particularly serialization errors with transformers dependencies in BERT question-answering pipelines, while maintaining complete API compatibility and improving code architecture.

🎯 LATEST UPDATE: Applied universal structure standardization to adopt the new generic layout (src/mlflow/) with class names Model and Logger, eliminating blueprint-specific prefixes for better maintainability across all AI blueprints.

Summary of Changes

  • Primary Purpose: Eliminate MLflow 3.1.0 serialization errors and modernize deployment architecture for BERT question-answering
  • Technical Approach: Clean separation of concerns through models-from-code pattern with standalone model classes
  • Structure Standardization: Universal layout adoption (src/mlflow/) with generic class names (Model, Logger)
  • Scope: Complete architectural migration affecting model loading, logging, and deployment workflows

Technical Changes

Universal Structure Standardization ✨

File Structure Migration

BEFORE (Legacy Structure):
notebooks/register-model.ipynb
├── DistilBERTModel(mlflow.pyfunc.PythonModel)  # Inline class definition
└── Direct MLflow inheritance with business logic

AFTER (Universal Structure):
src/mlflow/
├── __init__.py          # Exports: Model, Logger
├── model.py             # Class: Model (BERT QA business logic)
├── loader.py            # References: src.mlflow.model, Model
└── logger.py            # Class: Logger (Registration layer)

Generic Class Names

  • Model (extracted from DistilBERTModel): Framework-agnostic BERT question-answering business logic
  • Logger (replaces inline registration): MLflow registration and artifact management layer
  • Universal imports: from src.mlflow import Logger
  • Standardized loader module: loader_module="src.mlflow.loader"

New Architecture Components

loader.py (NEW Universal Structure)

  • Purpose: MLflow models-from-code entry point implementing the required _load_pyfunc() function
  • Functionality:
    • Loads configuration and optional trained model artifacts from MLflow artifacts
    • Handles proper artifact directory structure validation for BERT models
    • Returns initialized Model instance for prediction
  • Integration: Called automatically by MLflow during model loading and deployment

model.py (NEW Universal Structure)

  • Purpose: Standalone BERT question-answering business logic layer with zero MLflow dependencies
  • Architecture: Framework-agnostic model class designed for testability and maintainability
  • Functionality:
    • Complete BERT QA pipeline implementation: transformers pipeline initialization, preprocessing, prediction
    • Supports HuggingFace model checkpoints with GPU/CPU device handling
    • Maintains identical predict(model_input, params) API signature for backward compatibility
    • Handles all preprocessing operations: context/question extraction and validation
  • Design Pattern: Clean separation between business logic and MLflow integration concerns

Refactored Service Architecture

logger.py (NEW Universal Structure)

  • Role Transformation: Pure MLflow registration layer replacing inline DistilBERTModel class
  • Architectural Changes:
    • Eliminated MLflow inheritance dependencies (PythonModel removed)
    • Streamlined log_model() method using loader_module approach exclusively
    • Implemented artifact organization with proper temporary directory management
    • Updated to use universal loader module reference: src.mlflow.loader
  • Artifact Management:
    /artifacts/data/
      ├── config.yaml          # Model configuration
      ├── model/                # Trained BERT model directory (optional)
      └── demo/                 # UI components (optional)
    

Package Structure Enhancement

  • src/mlflow/__init__.py (NEW): Universal module initialization with generic exports
  • Notebooks Updated: All imports changed from inline class definition to src.mlflow
  • Clean API: Dynamic imports with backward compatibility for Model and Logger classes

Configuration & Environment Changes

Configuration Updates

  • requirements.txt: Upgraded to mlflow==3.1.0 for models-from-code support
  • Notebooks: Updated model registration to use new Logger instead of inline DistilBERTModel

Utility Function Enhancements

  • get_model_path(): Added utility function for container-aware model path resolution
  • Environment Integration: Improved support for container environments with MODEL_ARTIFACTS_PATH

Implementation Details

Architecture Impact

  • Design Pattern: Clean layered architecture with separation of concerns
    • Registration Layer: Logger (MLflow integration only)
    • Business Logic Layer: Model (framework-agnostic BERT QA functionality)
    • Loader Layer: loader (MLflow deployment interface)
  • Integration Points: Maintained identical external API for seamless migration
  • Performance Considerations: Eliminated serialization overhead, improved model loading efficiency

Code Organization

  • File Structure Changes:
    • Added: src/mlflow/ package with universal structure
    • Added: Standalone model class with comprehensive BERT QA functionality
    • Removed: Inline DistilBERTModel class from notebook
    • Modified: Notebooks updated for universal imports and new registration approach
  • Module Interactions: Clean imports with explicit dependency management and generic class names
  • Data Flow: Streamlined artifact handling through temp directory organization

Error Resolution Strategy

  • Serialization Issues: Eliminated cloudpickle dependency conflicts with transformers library
  • MLflow Compatibility: Full MLflow 3.1.0 support through models-from-code pattern
  • Error Handling: Comprehensive exception handling with detailed logging throughout initialization
  • Fallback Mechanisms: Graceful degradation for missing optional components (trained models, demo assets)

Testing Strategy

Manual Testing

  • Test Scenarios:
    • Model registration with HuggingFace model checkpoints
    • Model loading and prediction with question-answering inputs
    • Deployment validation through MLflow serving
    • Notebook execution validation in both development and MLflow deployment contexts

Quality Assurance

Code Quality

  • Code Style: Consistent with repository standards, comprehensive docstrings, proper type hints
  • Documentation: Clear architectural layer responsibilities, detailed function documentation
  • Error Handling: Robust exception management with informative error messages and logging
  • Universal Structure: Standardized layout improves maintainability across blueprints

Performance Impact

  • Model Loading: Faster initialization due to eliminated serialization overhead
  • Memory Usage: Reduced memory footprint by removing unnecessary inheritance
  • Deployment Time: Improved deployment reliability with models-from-code approach

Review Guidelines

Critical Review Areas

  1. MLflow Integration: Verify loader.py correctly implements models-from-code pattern with universal imports
  2. API Compatibility: Confirm Model.predict() maintains identical signature and behavior for BERT QA
  3. Artifact Handling: Validate proper organization and cleanup of temporary directories
  4. Configuration Management: Review HuggingFace model checkpoint handling and environment variables
  5. Error Scenarios: Test behavior with missing or invalid artifacts/configurations
  6. Universal Structure: Confirm generic class names and imports work correctly

Testing Instructions

  1. Register Model: Run notebooks/register-model.ipynb to validate new logging approach with universal structure
  2. Load and Test: Verify model loads correctly in MLflow UI and responds to API calls
  3. Deploy Validation: Confirm question-answering functionality with context/question inputs
  4. Migration Comparison: Compare before/after behavior for identical input scenarios
  5. Notebook Validation: Execute registration notebook to verify import and model logging functionality

Deployment Considerations

  • Rollback Procedure: Previous python_model approach is incompatible with models-from-code
  • Environment Setup: Ensure MLflow 3.1.0 compatibility in target deployment environments
  • Dependencies: Verify transformers library compatibility and GPU/CPU device handling
  • Universal Structure: New standardized layout (src/mlflow/) will be consistent across all blueprints

Commit History Summary

The development progression demonstrates systematic architectural migration:

  1. Initial Implementation: Created foundational models-from-code structure
  2. Business Logic Extraction: Developed standalone Model with full BERT QA functionality
  3. Service Layer Refactoring: Simplified registration to pure MLflow responsibilities
  4. Configuration Enhancement: Added model path configuration and notebook updates
  5. Utility Integration: Enhanced utilities for container-aware path resolution
  6. Universal Structure Migration: Applied standardized layout with generic class names and universal imports
  7. Final Refinement: Code cleanup, documentation improvements, and logging enhancements

Breaking Changes

None - This migration maintains complete API compatibility:

  • ✅ Identical model signature and parameter schema for question-answering
  • ✅ Unchanged notebook interfaces and method calls (imports updated to universal structure)
  • ✅ Same input/output format: {'context': [...], 'question': [...]}
  • ✅ Compatible demo and UI components
  • ✅ Universal structure provides consistency across blueprints

Future Considerations

Technical Debt Resolution

  • Dependency Management: Remove temporary MLflow version pin upon completion
  • Testing Coverage: Expand automated test suite for edge cases and error scenarios
  • Documentation: Update architecture diagrams and deployment guides

Blueprint Migration Template

This implementation provides a reusable migration pattern for other AI blueprints:

  1. Create loader.py in src/mlflow/ with _load_pyfunc function
  2. Develop Model class without MLflow inheritance in src/mlflow/model.py
  3. Update Logger.log_model() to use loader_module="src.mlflow.loader" approach
  4. Add comprehensive error handling and logging throughout
  5. Maintain API compatibility through identical method signatures
  6. Apply universal structure with generic class names and standardized layout

Migration Status:Complete with Universal Structure and Ready for Review

This comprehensive architectural migration successfully modernizes the Question Answering with BERT blueprint for MLflow 3.1.0 while adopting the universal structure standard that improves consistency and maintainability across all AI blueprints.

ata-turhan and others added 4 commits August 29, 2025 10:34
…proach

- Replace MNISTModel(mlflow.pyfunc.PythonModel) with models-from-code architecture
- Add src/mlflow/model.py with pure business logic for MNIST classification
- Add src/mlflow/loader.py for MLflow artifact loading
- Add src/mlflow/logger.py for model registration
- Update register-model.ipynb to use new Logger approach
- Add model_path configuration to config.yaml
- Update MLflow dependency to 3.1.0 in requirements.txt
- Add get_model_path utility function
- Eliminate MLflow serialization issues through clean architecture separation
… approach

- Create standalone Model class with BERT question-answering business logic
- Add MLflow loader and logger modules using models-from-code pattern
- Update register-model notebook to use new Logger instead of legacy PythonModel
- Upgrade MLflow to 3.1.0 to resolve serialization issues
- Add get_model_path utility function for artifact resolution
- Maintain identical functionality while eliminating MLflow inheritance
- Enable clean separation between business logic and MLflow integration
@github-actions github-actions bot added enhancement Improvements to existing features dependencies Pull requests that update a dependency file python Pull requests that update python code labels Sep 3, 2025
@NickyJhames NickyJhames changed the title feat: migrate question-answering-with-bert to MLflow models-from-code approach feat: MLflow 3.1.0 Models-from-Code Migration for Question Answering with BERT Blueprint Sep 3, 2025
@njhames njhames marked this pull request as draft September 4, 2025 13:38
@ata-turhan ata-turhan force-pushed the feat/mlflow-models-from-code-migration-question-answering-with-bert branch from 9b4caf3 to 7b7410c Compare September 25, 2025 15:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file enhancement Improvements to existing features python Pull requests that update python code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants