Skip to content

Upgrade protobuf generation code and add a new generate_protos.py script#12360

Merged
WeichenXu123 merged 25 commits into
mlflow:masterfrom
WeichenXu123:upgrade-proto2
Jun 21, 2024
Merged

Upgrade protobuf generation code and add a new generate_protos.py script#12360
WeichenXu123 merged 25 commits into
mlflow:masterfrom
WeichenXu123:upgrade-proto2

Conversation

@WeichenXu123

@WeichenXu123 WeichenXu123 commented Jun 14, 2024

Copy link
Copy Markdown
Contributor
🛠 DevTools 🛠

Open in GitHub Codespaces

Install mlflow from this PR

pip install git+https://github.com/mlflow/mlflow.git@refs/pull/12360/merge

Checkout with GitHub CLI

gh pr checkout 12360

Related Issues/PRs

closes #11811

What changes are proposed in this pull request?

Since protobuf python runtime version 5.26.0, it is not compatible with python gencode generated by protoc 3.19.4,
and according to https://protobuf.dev/support/cross-version-runtime-guarantee/#backwards,
New Gencode + Old Runtime is not allowed.
So to make MLflow supports either protobuf runtime version >= 5.26 or < 5.26, I make each python protobuf gencode module like:

import google.protobuf
from packaging.version import Version
if Version(google.protobuf.__version__) >= Version("5.26.0"):
   # code generated by protoc 5.26.0
else:
   # code generated by protoc 3.19.0

I also write a new generate_protos.py script so that it can automatically generates above multiple version bundled gencode python module.

How is this PR tested?

  • Existing unit/integration tests
  • New unit/integration tests
  • Manual tests

Does this PR require documentation update?

  • No. You can skip the rest of this section.
  • Yes. I've updated:
    • Examples
    • API references
    • Instructions

Release Notes

Is this a user-facing change?

  • No. You can skip the rest of this section.
  • Yes. Give a description of this change to be included in the release notes for MLflow users.

What component(s), interfaces, languages, and integrations does this PR affect?

Components

  • area/artifacts: Artifact stores and artifact logging
  • area/build: Build and test infrastructure for MLflow
  • area/deployments: MLflow Deployments client APIs, server, and third-party Deployments integrations
  • area/docs: MLflow documentation pages
  • area/examples: Example code
  • area/model-registry: Model Registry service, APIs, and the fluent client calls for Model Registry
  • area/models: MLmodel format, model serialization/deserialization, flavors
  • area/recipes: Recipes, Recipe APIs, Recipe configs, Recipe Templates
  • area/projects: MLproject format, project running backends
  • area/scoring: MLflow Model server, model deployment tools, Spark UDFs
  • area/server-infra: MLflow Tracking server backend
  • area/tracking: Tracking Service, tracking client APIs, autologging

Interface

  • area/uiux: Front-end, user experience, plotting, JavaScript, JavaScript dev server
  • area/docker: Docker use across MLflow's components, such as MLflow Projects and MLflow Models
  • area/sqlalchemy: Use of SQLAlchemy in the Tracking Service or Model Registry
  • area/windows: Windows support

Language

  • language/r: R APIs and clients
  • language/java: Java APIs and clients
  • language/new: Proposals for new client languages

Integrations

  • integrations/azure: Azure and Azure ML integrations
  • integrations/sagemaker: SageMaker integrations
  • integrations/databricks: Databricks integrations

How should the PR be classified in the release notes? Choose one:

  • rn/none - No description will be included. The PR will be mentioned only by the PR number in the "Small Bugfixes and Documentation Updates" section
  • rn/breaking-change - The PR will be mentioned in the "Breaking Changes" section
  • rn/feature - A new user-facing feature worth mentioning in the release notes
  • rn/bug-fix - A user-facing bug fix worth mentioning in the release notes
  • rn/documentation - A user-facing documentation change worth mentioning in the release notes

Should this PR be included in the next patch release?

Yes should be selected for bug fixes, documentation updates, and other small changes. No should be selected for new features and larger changes. If you're unsure about the release classification of this PR, leave this unchecked to let the maintainers decide.

What is a minor/patch release?
  • Minor release: a release that increments the second part of the version number (e.g., 1.2.0 -> 1.3.0).
    Bug fixes, doc updates and new features usually go into minor releases.
  • Patch release: a release that increments the third part of the version number (e.g., 1.2.0 -> 1.2.1).
    Bug fixes and doc updates usually go into patch releases.
  • Yes (this PR will be cherry-picked and included in the next patch release)
  • No (this PR will be included in the next minor release)

Signed-off-by: Weichen Xu <[email protected]>
Signed-off-by: Weichen Xu <[email protected]>
Comment on lines +2 to +4
import google.protobuf
from packaging.version import Version
if Version(google.protobuf.__version__) >= Version("5.26.0"):

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each pb module checks protobuf runtime version first, then executes matched gencode.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these gencode (including multiple version gencode) are generated by generate_protos.py script.

Signed-off-by: Weichen Xu <[email protected]>
Signed-off-by: Weichen Xu <[email protected]>
Signed-off-by: Weichen Xu <[email protected]>
Signed-off-by: Weichen Xu <[email protected]>
@harupy

harupy commented Jun 17, 2024

Copy link
Copy Markdown
Member

how do we ensure both the 5.26.0 code and the 3.19.0 code work?

@WeichenXu123

Copy link
Copy Markdown
Contributor Author

Note java pom.xml already shades google protobuf:
See

<include>com.google.protobuf:protobuf-java</include>

We can verify it by command:

cd mlflow/java
mvn clean package -Dmaven.test.skip=true -Dproject.build.sourceEncoding=UTF-8

jar -tf client/target/mlflow-client-2.13.3-SNAPSHOT.jar | grep "mlflow_project/google/protobuf"

outputs:

org/mlflow_project/google/protobuf/
org/mlflow_project/google/protobuf/AbstractMessage$Builder.class
org/mlflow_project/google/protobuf/AbstractMessage$BuilderParent.class
org/mlflow_project/google/protobuf/AbstractMessage.class
org/mlflow_project/google/protobuf/AbstractMessageLite$Builder$LimitedInputStream.class
org/mlflow_project/google/protobuf/AbstractMessageLite$Builder.class
org/mlflow_project/google/protobuf/AbstractMessageLite$InternalOneOfEnum.class
org/mlflow_project/google/protobuf/AbstractMessageLite.class
org/mlflow_project/google/protobuf/AbstractParser.class
...

@WeichenXu123

Copy link
Copy Markdown
Contributor Author

how do we ensure both the 5.26.0 code and the 3.19.0 code work?

I will add CI for it.

Comment thread dev/generate_protos.py
], "The script only supports MacOS or Linux system."
assert platform.machine() in [
"x86_64",
"aarch64",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to support arm64 CPU as well?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have machine to test that. We can add it when we receive the use-case.

Comment thread dev/generate_protos.py
return "\n".join(lines)


def generate_final_python_gencode(gencode3194_path, gencode5260_path, out_path):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is clever

@github-actions

github-actions Bot commented Jun 18, 2024

Copy link
Copy Markdown
Contributor

Documentation preview for 4ec2ec7 will be available when this CircleCI job
completes successfully.

More info

Signed-off-by: Weichen Xu <[email protected]>
Signed-off-by: Weichen Xu <[email protected]>
Signed-off-by: Weichen Xu <[email protected]>
Signed-off-by: Weichen Xu <[email protected]>
Signed-off-by: Weichen Xu <[email protected]>
@WeichenXu123
WeichenXu123 requested a review from BenWilson2 June 19, 2024 09:50
@github-actions github-actions Bot added area/tracking Tracking service, tracking client APIs, autologging and removed area/tracking Tracking service, tracking client APIs, autologging labels Jun 19, 2024
Comment thread .github/workflows/protobuf-cross-test.yml Outdated
Comment thread .github/workflows/protobuf-cross-test.yml Outdated
Comment thread dev/generate_protos.py Outdated
Comment thread dev/generate_protos.py
Comment thread dev/generate_protos.py Outdated
Signed-off-by: Weichen Xu <[email protected]>
Signed-off-by: Weichen Xu <[email protected]>
Signed-off-by: Weichen Xu <[email protected]>
Signed-off-by: Weichen Xu <[email protected]>
Signed-off-by: Weichen Xu <[email protected]>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/ai hello, fix this github action workflow. Please make the following updates:

  • protobuf_major_version_plus_one is confusing. Rename it to protobuf_major_version and increment the version before pip install.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@harupy

Sure, here's how you can update the code snippet:

jobs:
  core_tests:
    if: github.event_name != 'pull_request' || github.event.pull_request.draft == false
    runs-on: ubuntu-latest
    timeout-minutes: 120
    strategy:
      fail-fast: false
      matrix:
        group: [1, 2]
-       protobuf_major_version_plus_one: [4, 5, 6]
+       protobuf_major_version: [3, 4, 5]
        include:
          - splits: 2
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: recursive
      - uses: ./.github/actions/untracked
      - uses: ./.github/actions/free-disk-space
      - uses: ./.github/actions/setup-python
      - uses: ./.github/actions/setup-pyenv
      - uses: ./.github/actions/setup-java
      - name: Install dependencies
        run: |
          pip install --no-dependencies tests/resources/mlflow-test-plugin
          pip install .[extras]
          pip install pyspark
          # Install Hugging Face datasets to test Hugging Face usage with MLflow dataset tracking
          pip install datasets
          # Install TensorFlow to test TensorFlow dataset usage with MLflow dataset tracking
          pip install tensorflow
          # Install torch and transformers to test metrics
          pip install torch transformers
          pip install -r requirements/test-requirements.txt
          # Test against specific protobuf version
-         pip install "protobuf<${{ matrix.protobuf_major_version_plus_one }}"
+         protobuf_incremented_version=$((${{ matrix.protobuf_major_version }} + 1))
+         pip install "protobuf<${protobuf_incremented_version}"
      - uses: ./.github/actions/pipdeptree
      - name: Run tests
        run: |
          pytest --splits=${{ matrix.splits }} --group=${{ matrix.group }} \
            --ignore-flavors --ignore=tests/projects --ignore=tests/examples --ignore=tests/recipes --ignore=tests/evaluate --ignore tests/deployments/server \
            tests

This changes the confusing protobuf_major_version_plus_one to protobuf_major_version and increments the version number before passing it to pip install.

Click here to see the usage data
{
  "prompt_tokens": 893,
  "completion_tokens": 480,
  "total_tokens": 1373,
  "estimated_cost_in_usd": 0.05559
}

@harupy harupy Jun 20, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@WeichenXu123 you can try this. I think it works.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's because you used ${{ protobuf_incremented_version }}, not ${protobuf_incremented_version} or $protobuf_incremented_version.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh got it!

@WeichenXu123 WeichenXu123 Jun 21, 2024

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting , it failed again using ${protobuf_incremented_version}: https://github.com/mlflow/mlflow/actions/runs/9606814485/job/26496930964?pr=12360 @harupy

/home/runner/work/_temp/6ae75bcc-0fce-4971-9e2b-b916fb7e6c16.sh: line 13: protobuf<${ protobuf_incremented_version }: bad substitution

@harupy harupy Jun 21, 2024

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@WeichenXu123

% FOO=foo
                                                                                                 
% echo "${ FOO }"
zsh: bad substitution
                                                                                                 
% echo "${FOO}"
foo

@WeichenXu123 WeichenXu123 Jun 21, 2024

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this works too protobuf<$protobuf_incremented_version

Signed-off-by: Weichen Xu <[email protected]>
Signed-off-by: Weichen Xu <[email protected]>
Comment thread dev/generate_protos.py Outdated
Comment thread dev/generate_protos.py
Comment thread .github/workflows/protobuf-cross-test.yml Outdated
@harupy

harupy commented Jun 21, 2024

Copy link
Copy Markdown
Member

@BenWilson2 could you also take another look?

Signed-off-by: Weichen Xu <[email protected]>

@harupy harupy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@BenWilson2 BenWilson2 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +79 to +81
pytest --splits=${{ matrix.splits }} --group=${{ matrix.group }} \
--ignore-flavors --ignore=tests/projects --ignore=tests/examples --ignore=tests/recipes --ignore=tests/evaluate --ignore tests/deployments/server \
tests

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be a follow-up. does this run tests unrelated to protobuf?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes. We can filter out tests unrelated to protobuf, but no simple rules currently

Signed-off-by: Weichen Xu <[email protected]>
@WeichenXu123
WeichenXu123 merged commit a4c7f21 into mlflow:master Jun 21, 2024
@WeichenXu123

Copy link
Copy Markdown
Contributor Author

oh, I found an issue:

+ pip install 'protobuf<6'
Requirement already satisfied: protobuf<6 in /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages (4.25.3)

I will file a follow-up PR.

@villainb-dg

Copy link
Copy Markdown

Any idea when this PR will be released? The upgrade of protobuf requirements to 6+ is blocking us from upgrade grpcio past 1.63.0. Thanks

@BenWilson2

Copy link
Copy Markdown
Contributor

@villainb-dg late next week :)

@villainb-dg

Copy link
Copy Markdown

@BenWilson2 So it seems that the latest release 4.12.3 did not include your change (https://github.com/mlflow/mlflow/blob/v2.14.3/pyproject.toml#L45). Any idea why?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/tracking Tracking service, tracking client APIs, autologging rn/bug-fix Mention under Bug Fixes in Changelogs.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] AttributeError: type object 'FileOptions' has no attribute 'RegisterExtension'

4 participants