Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PINNED: diff against upstream #1

Draft
wants to merge 181 commits into
base: main
Choose a base branch
from
Draft

Conversation

jokester
Copy link
Member

@jokester jokester commented Feb 18, 2024

moeflow-com/moeflow#5

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new GroqTranslator class for translations using the GROQ API.
    • Added new environment variables for OpenAI and Google Cloud services in .env.sample.
    • New Celery-based worker for processing manga image translation tasks.
    • Added functionality for uploading image files using Streamlit.
  • Improvements

    • Enhanced type safety and error handling across various components.
    • Updated documentation in the README with installation and configuration instructions.
    • Introduced an asynchronous caching mechanism for Streamlit functions.
  • Bug Fixes

    • Improved handling of existing files in the translation process to prevent errors.
  • Chores

    • Updated .dockerignore and .gitignore to streamline ignored files.
    • Added groq as a new dependency in requirements.txt.

@jokester jokester changed the title DIFF moeflow-companion-main ... origin/main Run models as a Celery task worker Feb 29, 2024
@jokester jokester self-assigned this Feb 29, 2024
@jokester jokester force-pushed the moeflow-companion-main branch from 1dbd75e to 1f9a719 Compare March 4, 2024 15:06
@jokester
Copy link
Member Author

TODO

  • create a clean & working poetry.yaml. The one in MIT repo conflicts with other packages I want to add

@jokester jokester force-pushed the moeflow-companion-main branch from 7ed4d15 to 2747b70 Compare April 20, 2024 04:10
@jokester jokester marked this pull request as ready for review June 1, 2024 11:05
@jokester jokester force-pushed the moeflow-companion-main branch from 03659b4 to e8f99bf Compare July 2, 2024 16:01
Copy link

coderabbitai bot commented Oct 26, 2024

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The changes in this pull request encompass various modifications across multiple files, including the addition of new environment variables, the introduction of a new GitHub Actions workflow, and the creation of a new Dockerfile. Key updates include adjustments to the .dockerignore and .gitignore files, enhancements to the Makefile, and the addition of a new GroqTranslator class. Additionally, several functions and methods have been updated for better type safety and error handling, along with the introduction of a new Celery worker for processing manga image translation tasks.

Changes

File Change Summary
.dockerignore Added venv and .git to ignored entries; removed /venv.
.env.sample Added OPENAI_API_KEY, GOOGLE_APPLICATION_CREDENTIALS, CELERY_BROKER_URL, and CELERY_BACKEND_URL.
.github/workflows/mit-worker-image.yml New workflow for building and pushing Docker images triggered by specific events.
.gitignore Added venv; removed /venv.
Dockerfile.moeflow_worker New Dockerfile using continuumio/miniconda3, installs packages, and sets up a conda environment.
Makefile Added new targets: default, conda-env, run-worker, prepare-models; modified run-web-server.
README_moeflow_worker.md New section "HOWTOs" added for installation and configuration instructions.
conda.yaml New file defining conda environment mit-py311 with specified channels and dependencies.
manga_translator/__init__.py Commented out import statement for all entities from the module.
manga_translator/detection/__init__.py Added comment for CRAFTDetector in DETECTORS dictionary.
manga_translator/manga_translator.py Enhanced type annotations, error handling, and control flow in translation methods.
manga_translator/ocr/model_48px.py Added comment in _infer method regarding directory creation for OCR results.
manga_translator/ocr/model_manga_ocr.py Updated merge_bboxes return type; improved error handling in _infer method.
manga_translator/translators/__init__.py Commented out multiple translator imports; added GroqTranslator.
manga_translator/translators/groq.py New class GroqTranslator for translations using the GROQ API.
manga_translator/translators/keys.py Added environment variable for GROQ_API_KEY.
manga_translator/utils/generic.py Updated function signatures for atoi, load_image, and count_valuable_text for better type clarity.
manga_translator/utils/inference.py Updated _check_downloaded_map return type to bool; added _grant_execute_permissions method.
manga_translator/utils/textblock.py Updated __init__ method parameter type for TextBlock class for better type safety.
moeflow_worker.py Introduced a Celery-based worker with tasks for text detection, OCR, and translation.
requirements.txt Added groq package as a new dependency.
manga_translator/streamlit/__init__.py New functionality for handling translation tasks asynchronously; added TranslateTaskDef model.
manga_translator/streamlit/cache_async.py New asynchronous caching mechanism for functions in Streamlit applications.
manga_translator/streamlit/pages/demo-upload.py New functionality for uploading image files using Streamlit.
manga_translator/streamlit/pages/mit-moeflow.py Integrated Pydantic models with Streamlit forms for structured input handling.
manga_translator/streamlit/pages/mit.py New file with a simple markdown display.
manga_translator/streamlit/pages/page1.py Introduced user input elements and logging functionality in a Streamlit application page.

Poem

In the garden of code where changes bloom,
New paths for the worker, dispelling the gloom.
With Groq by our side, translations take flight,
In the world of manga, we bring forth the light!
So hop with delight, let the tasks intertwine,
For every new feature, our code will align! 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Experiment)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 21

🧹 Outside diff range and nitpick comments (17)
Makefile (1)

1-14: Clarify the environment management strategy.

The Makefile introduces conda-based targets while the project appears to be transitioning between different environment management tools (poetry, conda, Docker). Consider:

  1. Documenting the rationale for using multiple environment management tools
  2. Ensuring consistent environment setup across development and production
  3. Providing clear migration guidelines for developers
manga_translator/translators/keys.py (2)

17-17: Clean up TODO comment.

The TODO comment about replacing OPENAI_HTTP_PROXY with --proxy should be addressed as part of maintaining clean code.

Would you like me to help create an issue to track this TODO item?


Line range hint 1-33: Consider improving configuration robustness and documentation.

  1. The empty string defaults for API keys could lead to silent failures. Consider raising explicit exceptions when required keys are missing.
  2. The file contains mixed language comments (English/Chinese). Consider standardizing to English for better maintainability.

Here's a suggested pattern for more robust key handling:

def get_required_env(key: str, default: str | None = None) -> str:
    value = os.getenv(key, default)
    if not value:
        raise ValueError(f"Missing required environment variable: {key}")
    return value

# Example usage:
GROQ_API_KEY = get_required_env('GROQ_API_KEY')  # Will raise if not set
# For optional keys:
OPENAI_HTTP_PROXY = os.getenv('OPENAI_HTTP_PROXY')  # Can be None
.github/workflows/mit-worker-image.yml (2)

3-9: Consider adding 'develop' branch to the trigger list.

The workflow currently triggers on main and moeflow-* branches. Since the metadata action includes tagging for the develop branch (line 43), consider adding it to the trigger list for consistency.

  push:
    branches:
      - main
+     - develop
      - moeflow-*

26-28: Add existence check before cleanup.

The cleanup step might fail if the directory doesn't exist. Add a check to make the workflow more robust.

- run: rm -rf /opt/hostedtoolcache
+ run: |
+   if [ -d "/opt/hostedtoolcache" ]; then
+     rm -rf /opt/hostedtoolcache
+   fi
manga_translator/utils/inference.py (3)

281-289: Enhance docstring to document side effects.

The implementation looks good, but the docstring could be more comprehensive by mentioning that this method also triggers permission updates via _grant_execute_permissions.

Consider updating the docstring:

     def _check_downloaded_map(self, map_key: str) -> bool:
         """Check if model file exists
 
         Args:
             map_key (str): key in self._MODEL_MAPPING
 
         Returns:
             bool: the "file" or "archive" file exists
+
+        Note:
+            This method also updates file permissions on Linux systems by calling
+            _grant_execute_permissions if the files exist.
         """

Line range hint 314-326: Add error handling and logging for permission changes.

While the implementation is correct, consider adding try-catch for chmod operations and logging for better observability.

Consider updating the implementation:

     def _grant_execute_permissions(self, map_key: str):
         mapping = self._MODEL_MAPPING[map_key]
 
         if sys.platform == 'linux':
             # Grant permission to executables
             for file in mapping.get('executables', []):
                 p = self._get_file_path(file)
                 if os.path.basename(p) in ('', '.'):
                     p = os.path.join(p, file)
                 if not os.path.isfile(p):
                     raise InvalidModelMappingException(self._key, map_key, f'File "{file}" does not exist')
                 if not os.access(p, os.X_OK):
-                    os.chmod(p, os.stat(p).st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
+                    try:
+                        os.chmod(p, os.stat(p).st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
+                        self.logger.debug(f"Granted execute permissions to {p}")
+                    except OSError as e:
+                        self.logger.warning(f"Failed to set execute permissions for {p}: {e}")

Line range hint 281-326: Consider distributed environment challenges.

Since this code will run in a Celery worker environment, a few architectural considerations:

  1. File system operations should be atomic to handle concurrent workers
  2. Consider adding file locking during permission changes
  3. Add metrics/monitoring for file operations in distributed setup

Would you like help implementing these distributed environment safeguards?

manga_translator/utils/textblock.py (1)

Line range hint 379-382: Consider cleaning up or documenting commented code

There are large sections of commented-out code that appear to contain potentially useful implementations. If these implementations are no longer needed, consider removing them. If they are planned for future use, add TODO comments explaining the plan.

manga_translator/ocr/model_48px.py (2)

91-91: Address the FIXME comment regarding temporary directory usage.

Using a hardcoded directory for OCR results can cause issues with permissions, disk space, and concurrent access. Let's implement a proper solution using temporary directories.

Would you like me to help implement a solution using tempfile.mkdtemp() that ensures proper cleanup of temporary files? This would:

  1. Create a unique temporary directory for each inference
  2. Automatically clean up files after use
  3. Handle concurrent access safely

Line range hint 1-1024: Consider restructuring for Celery task worker integration.

Since this PR aims to run models as Celery task workers, consider the following architectural improvements:

  1. The OCR inference operations are CPU-intensive and should be offloaded to Celery workers
  2. The async methods (_load, _unload, _infer) perform blocking operations that could impact performance

Consider:

  1. Wrapping the inference logic in a Celery task
  2. Using proper async IO operations for file operations
  3. Implementing a result backend for storing OCR results instead of using the filesystem

Example Celery task structure:

from celery import shared_task

@shared_task
def ocr_inference_task(image_data: bytes, textlines: List[dict]) -> List[dict]:
    model = Model48pxOCR()
    # Perform inference and return results
    return results
manga_translator/translators/groq.py (2)

40-40: Fix typo in _CHAT_SYSTEM_TEMPLATE

There's a typo in the _CHAT_SYSTEM_TEMPLATE. The word "currenly" should be "currently".

Apply this diff to correct the typo:

-            'You will try to understand the context of the story by reading previous and currenly provided sentences'
+            'You will try to understand the context of the story by reading previous and currently provided sentences'

41-41: Improve grammar for clarity in _CHAT_SYSTEM_TEMPLATE

The sentence structure can be improved for better readability.

Apply this diff to enhance clarity:

-            'Understand that this is being used as a manga translator, so the translation should retain some words from the original text. Like Senpai should not be translated to "senior" in this context. but kept as Senpai'
+            'Understand that this is being used as a manga translator, so the translation should retain some words from the original text. For example, "Senpai" should not be translated to "senior" in this context but kept as "Senpai".'
moeflow_worker.py (2)

12-13: Address the FIXME comments to improve the translator implementation

There are FIXME comments suggesting the implementation of a better translator, possibly with Langchain, and the creation of a different translators package. Resolving these will enhance the translation functionality and maintainability of the code.

Would you like assistance in implementing the improved translator or setting up a separate translators package? I can help with code suggestions or open a new GitHub issue to track this task.


119-119: Implement mit_inpaint function or handle NotImplementedError appropriately

The mit_inpaint function currently raises NotImplementedError. Ensure that this is intentional and consider providing a fallback mechanism or implementing the function to handle inpainting tasks.

Would you like assistance in implementing the mit_inpaint function or creating a placeholder that handles this case more gracefully? I can help develop the implementation or open a GitHub issue to track this task.

manga_translator/manga_translator.py (2)

Line range hint 398-404: Refine exception handling during language detection

Catching the general Exception may mask unexpected errors. It's better to catch the specific LangDetectException from the langdetect library to handle known issues while allowing unforeseen exceptions to propagate appropriately.

Replace the generic exception with the specific one:

 try:
     source_language = LANGDETECT_MAP.get(langdetect.detect(txtln.text), 'UNKNOWN')
-except Exception:
+except langdetect.lang_detect_exception.LangDetectException:
     source_language = 'UNKNOWN'

Line range hint 704-708: Add retry limit or delay to prevent potential infinite loop

In _send_state, if an exception occurs and finished is True, the continue statement will cause the loop to retry indefinitely without a delay. This could lead to an infinite loop and overload the server.

Consider adding a retry limit or a delay between retries:

retry_count = 0
while retry_count < MAX_RETRIES:
    try:
        # existing code
        break
    except Exception:
        if finished:
            retry_count += 1
            time.sleep(DELAY_INTERVAL)
            continue
        else:
            break
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between aee21d9 and 337b359.

📒 Files selected for processing (21)
  • .dockerignore (1 hunks)
  • .env.sample (1 hunks)
  • .github/workflows/mit-worker-image.yml (1 hunks)
  • .gitignore (1 hunks)
  • Dockerfile.moeflow_worker (1 hunks)
  • Makefile (1 hunks)
  • README_moeflow_worker.md (1 hunks)
  • conda.yaml (1 hunks)
  • manga_translator/init.py (1 hunks)
  • manga_translator/detection/init.py (1 hunks)
  • manga_translator/manga_translator.py (11 hunks)
  • manga_translator/ocr/model_48px.py (1 hunks)
  • manga_translator/ocr/model_manga_ocr.py (3 hunks)
  • manga_translator/translators/init.py (4 hunks)
  • manga_translator/translators/groq.py (1 hunks)
  • manga_translator/translators/keys.py (1 hunks)
  • manga_translator/utils/generic.py (2 hunks)
  • manga_translator/utils/inference.py (1 hunks)
  • manga_translator/utils/textblock.py (1 hunks)
  • moeflow_worker.py (1 hunks)
  • requirements.txt (1 hunks)
✅ Files skipped from review due to trivial changes (6)
  • .dockerignore
  • .env.sample
  • README_moeflow_worker.md
  • manga_translator/init.py
  • manga_translator/detection/init.py
  • requirements.txt
🧰 Additional context used
🪛 Ruff
manga_translator/translators/__init__.py

20-20: .qwen2.Qwen2Translator imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)


20-20: .qwen2.Qwen2BigTranslator imported but unused; consider removing, adding to __all__, or using a redundant alias

(F401)

manga_translator/translators/groq.py

2-2: asyncio imported but unused

Remove unused import: asyncio

(F401)


3-3: time imported but unused

Remove unused import: time

(F401)


4-4: json imported but unused

Remove unused import: json

(F401)


5-5: re imported but unused

Remove unused import: re

(F401)

moeflow_worker.py

53-53: Multiple isinstance calls for o, merge into a single call

Merge isinstance calls for o

(SIM101)


55-58: Combine if branches using logical or operator

Combine if branches

(SIM114)

🔇 Additional comments (17)
Dockerfile.moeflow_worker (2)

8-9: ⚠️ Potential issue

Enhance conda environment setup reliability

The conda environment setup lacks error handling and version pinning:

  1. Add environment activation verification
  2. Add error handling for the preparation script
  3. Consider pinning conda version
-RUN --mount=type=cache,target=/root/.conda conda env update --prune --file conda.yaml
-RUN conda run -n mit-py311 --no-capture-output python3 docker_prepare.py
+RUN --mount=type=cache,target=/root/.conda \
+    conda env update --prune --file conda.yaml && \
+    conda run -n mit-py311 python3 -c "import sys; sys.exit(0)" || exit 1
+
+RUN conda run -n mit-py311 --no-capture-output python3 docker_prepare.py || \
+    (echo "Model preparation failed" && exit 1)

Additionally, there's a potential conflict between the PR objectives mentioning poetry.yaml and the usage of conda.yaml here.

#!/bin/bash
# Check for poetry related files
echo "Checking for poetry files..."
fd -t f "poetry\.(lock|yaml|toml)$"

1-2: Verify CUDA support requirements

The switch from pytorch/pytorch:2.2.2-cuda12.1-cudnn8-runtime to continuumio/miniconda3 removes built-in CUDA support. Ensure that the model inference doesn't require GPU acceleration, or if it does, verify that CUDA dependencies are properly installed through conda.yaml.

✅ Verification successful

CUDA support is properly configured in conda environment

The switch from pytorch/pytorch to continuumio/miniconda3 base image is safe. The conda.yaml explicitly includes all necessary CUDA dependencies:

  • PyTorch 2.2.2 with CUDA 12.1 support (pytorch=2.2.2=py3.11_cuda12.1_cudnn8.9.2_0)
  • CUDA runtime components (cuda-runtime=12.1.0)
  • CUDA libraries and CUDNN
  • Proper channels configuration including pytorch and nvidia
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check if CUDA dependencies are specified in conda.yaml
rg -i "cuda|cudnn|pytorch.*cuda" conda.yaml

Length of output: 104


Script:

#!/bin/bash
# First, let's check if conda.yaml exists and see its contents
fd -t f "conda.yaml"
echo "---"
fd -t f "conda.yaml" -x cat {}

# Also check for any other environment files that might contain PyTorch/CUDA deps
fd -t f "(environment|requirements)\.(yaml|yml)$"
echo "---"
fd -t f "(environment|requirements)\.(yaml|yml)$" -x cat {}

Length of output: 3797

Makefile (2)

12-13: Clarify model preparation process and add error handling.

The target runs docker_prepare.py but provides no feedback or error handling. Consider:

  1. Adding a description of what models are being prepared
  2. Implementing status output and error handling
  3. Clarifying why this runs in conda despite the Docker-related name
#!/bin/bash
# Check the docker preparation script
if [ -f "docker_prepare.py" ]; then
    echo "Content of docker_prepare.py:"
    cat docker_prepare.py
else
    echo "Warning: docker_prepare.py not found"
fi

6-7: Verify conda environment setup requirements.

The target assumes conda and conda.yaml are available. Consider adding checks and better error handling.

.github/workflows/mit-worker-image.yml (2)

16-24: LGTM! Well-configured job permissions.

The job configuration follows security best practices by explicitly defining minimal required permissions.


46-57: 🛠️ Refactor suggestion

Verify Docker build configuration.

Several improvements could enhance the build step:

  1. The Dockerfile path needs to be verified
  2. Consider adding build arguments for version/commit information
  3. Add error handling for the build step

Consider adding build arguments for better traceability:

 with:
   context: .
   file: ./Dockerfile.moeflow_worker
   platforms: linux/amd64
   push: true
   provenance: false
   sbom: false
   tags: ${{ steps.docker_meta.outputs.tags }}
   cache-from: type=gha,scope=mit-worker-x64
   cache-to: type=gha,mode=max,scope=mit-worker-x64
+  build-args: |
+    COMMIT_SHA=${{ github.sha }}
+    VERSION=${{ steps.docker_meta.outputs.version }}
✅ Verification successful

Docker build configuration is valid but can be enhanced

The verification shows:

  • Dockerfile.moeflow_worker exists and uses conda for environment management
  • No poetry files are present, confirming conda is the package manager
  • No existing build-args in the workflow

While the basic configuration is correct, the suggested improvements for build arguments would indeed enhance traceability. The original review's concerns about Dockerfile existence and poetry conflicts are resolved, but the build-args suggestion remains valuable.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the existence of Dockerfile and related configurations

# Test 1: Check if Dockerfile exists
if [ ! -f "./Dockerfile.moeflow_worker" ]; then
    echo "Error: Dockerfile.moeflow_worker not found"
    exit 1
fi

# Test 2: Check for poetry.yaml mentioned in PR objectives
if [ -f "poetry.yaml" ]; then
    echo "Warning: poetry.yaml exists and might conflict with packages"
fi

Length of output: 69


Script:

#!/bin/bash
# Let's verify the Dockerfile existence and content more thoroughly
echo "=== Checking for Dockerfile ==="
fd "Dockerfile.moeflow_worker"

echo -e "\n=== Checking Dockerfile content if exists ==="
if [ -f "Dockerfile.moeflow_worker" ]; then
    head -n 20 Dockerfile.moeflow_worker
fi

echo -e "\n=== Looking for any poetry related files ==="
fd "poetry"

echo -e "\n=== Checking for existing build args in workflow ==="
rg "build-args?" ".github/workflows/mit-worker-image.yml"

Length of output: 1003

conda.yaml (2)

1-5: Environment configuration looks good but verify CUDA compatibility.

The environment is properly named and includes necessary channels for PyTorch and NVIDIA support.

Let's verify CUDA compatibility across dependencies:

✅ Verification successful

CUDA versions are consistent across the environment configuration

The verification shows that:

  • The conda environment uses CUDA 12.1 consistently across core CUDA packages (cuda-runtime, cuda-libraries, cuda-cudart, etc.)
  • PyTorch is properly configured with CUDA 12.1 (pytorch-cuda=12.1)
  • The only exception is cuda-opencl=12.4.127 which is not a concern as it's a separate OpenCL implementation
  • The codebase properly handles CUDA device availability checks and is compatible with the specified CUDA version
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for CUDA version consistency
rg "cuda-|cuda[^-]" | grep -i "version\|cuda.*=.*"

Length of output: 4114


1-132: Clarify package manager strategy.

The PR objectives mention creating a "clean and working poetry.yaml", but this PR introduces a conda.yaml instead. This raises some concerns:

  1. Are we switching from Poetry to Conda intentionally?
  2. Will this cause conflicts with existing Poetry dependencies?
  3. How will this affect the development workflow?

Let's check for existing Poetry configuration:

Consider:

  1. Document the rationale for using Conda instead of Poetry
  2. Ensure this aligns with the team's package management strategy
  3. Update the PR description to reflect this change in approach
manga_translator/ocr/model_manga_ocr.py (2)

150-152: LGTM! Improved error handling for args dictionary.

The use of args.get('use_mocr_merge', False) instead of direct dictionary access prevents KeyError exceptions and provides a sensible default.


29-29: Verify callers of merge_bboxes function.

The function signature change to include return type annotation improves type safety. However, this is a breaking change that requires verification of all callers.

✅ Verification successful

Let me analyze the results from the rg command to verify the impact of the merge_bboxes function signature change.

The search results show that merge_bboxes is:

  1. Defined in manga_translator/ocr/model_manga_ocr.py
  2. Called only once within the same file, where both return values are properly unpacked

Let me verify if this function is exported or used in other ways:


Let me check if the function is exposed through __all__ or if the module itself is imported:


Function signature change is safe to proceed

The merge_bboxes function is:

  • Only called once within its own file
  • Not exposed through __all__
  • Not imported directly in any other files
  • The only module import is for the class ModelMangaOCR, not the function

The change in return type annotation is localized and doesn't impact any other parts of the codebase.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for all callers of merge_bboxes
rg "merge_bboxes\(" --type py

Length of output: 330


Script:

#!/bin/bash
# Check if merge_bboxes is imported/used elsewhere
rg "from.*model_manga_ocr.*merge_bboxes|import.*model_manga_ocr.*merge_bboxes" --type py

Length of output: 90


Script:

#!/bin/bash
# Check if merge_bboxes is in __all__ and if the module is imported
echo "=== Checking __all__ in model_manga_ocr.py ==="
rg "__all__.*=.*" manga_translator/ocr/model_manga_ocr.py

echo -e "\n=== Checking imports of model_manga_ocr ==="
rg "from.*model_manga_ocr import|import.*model_manga_ocr" --type py

Length of output: 411

manga_translator/utils/textblock.py (1)

45-45: LGTM: Improved type safety with specific type annotation

The updated type annotation List[Tuple[int, int, int, int]] clearly defines the expected structure of the lines parameter, making it easier to catch type-related errors during development.

manga_translator/utils/generic.py (1)

68-68: LGTM: Type hints accurately reflect the function's behavior.

The updated signature atoi(text: str) -> int | str correctly specifies that the function accepts a string and returns either an integer or string.

moeflow_worker.py (3)

88-88: Clarify the comment regarding async_ocr return value

The comment mentions an unknown reason for async_ocr returning [[Quad]] instead of [result]. Investigate the cause to ensure the function behaves as expected, and update the comment to reflect any findings.

I recommend checking the return type of async_ocr and ensuring it aligns with the expected data structure. This will help prevent unexpected behaviors in downstream processing.


185-197: Ensure proper handling of asynchronous translation

The async_translate function uses await with the translator's methods and returns the result. Confirm that the translator supports asynchronous operations and that the Awaitable return type is correctly handled when using @async_to_sync.

Please verify that the translator's methods are compatible with the asynchronous context and that the result is correctly returned after synchronization.


93-99: ⚠️ Potential issue

Verify the order of image dimensions when unpacking shape

In NumPy, the shape of an image array is typically (height, width, channels). Ensure that img_h and img_w are assigned correctly to prevent dimension mismatches in subsequent processing.

Consider swapping img_w and img_h:

-    img_w, img_h, *_rest = load_rgb_image(path_or_url).shape
+    img_h, img_w, *_rest = load_rgb_image(path_or_url).shape

This adjustment ensures that width and height correspond to the correct dimensions when passed to async_textline_merge.

manga_translator/manga_translator.py (2)

121-121: Enhanced type annotations in translate_path method

Updating the params parameter type from dict to dict[str, Union[int, str]] improves type safety and clarifies the expected structure of the arguments.


225-225: Added return type annotation to _translate_file

Specifying the return type as -> bool enhances code readability and aids in static type checking, ensuring that the method's purpose is clear.

.gitignore Outdated
@@ -38,5 +38,5 @@ share/python-wheels/
.installed.cfg
*.egg
MANIFEST
venv
Copy link

Choose a reason for hiding this comment

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

💡 Codebase verification

Virtual environment patterns need consolidation in both .gitignore and .dockerignore

The verification confirms scattered virtual environment patterns that should be consolidated:

  • .gitignore has related patterns spread across lines 16-20, 36, and 41
  • .dockerignore has a single venv entry at line 10

For better maintainability, update both files:

  1. In .gitignore, consolidate under a single "Virtual Environment" section:
# Virtual Environment
venv/
.venv/
ENV/
env/
pyvenv.cfg
Scripts/
Lib/
include/
share/
  1. In .dockerignore, align with the same patterns:
# Virtual Environment
venv/
.venv/
ENV/
env/
🔗 Analysis chain

LGTM! Consider consolidating virtual environment patterns.

The change to use venv is more flexible than /venv and aligns well with Poetry usage. However, there are multiple virtual environment-related patterns scattered in the file (pyvenv.cfg, Scripts, Lib, etc.).

Consider consolidating all virtual environment patterns under a single section for better maintainability:

-pyvenv.cfg
-Scripts
-Lib
-include
-share
-venv
+# Virtual Environment
+venv/
+.venv/
+ENV/
+env/
+pyvenv.cfg

Let's verify there are no untracked virtual environment directories:

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any virtual environment directories that might be missed
# Expected: No output means no untracked virtual environment directories

# Look for common virtual environment directories and files
fd -H -I -t d '^(venv|env|\.venv|ENV)$' -x echo "Found virtual environment directory: {}"
fd -H -I -t f '^pyvenv.cfg$' -x echo "Found virtual environment config: {}"

Length of output: 169


Script:

#!/bin/bash
# Let's verify the current patterns in .gitignore and .dockerignore
# to ensure our consolidation suggestion is complete and accurate

# Check .gitignore for all virtual environment related patterns
echo "=== Virtual environment patterns in .gitignore ==="
rg -n "^(venv|env|\.venv|ENV|pyvenv|Scripts|Lib|include|share)" .gitignore

# Check .dockerignore for related patterns to ensure consistency
echo -e "\n=== Virtual environment patterns in .dockerignore ==="
if [ -f .dockerignore ]; then
    rg -n "^(venv|env|\.venv|ENV|pyvenv|Scripts|Lib|include|share)" .dockerignore
else
    echo ".dockerignore file not found"
fi

Length of output: 516

Comment on lines 4 to 5
RUN apt update \
&& DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install tzdata build-essential python3-opencv
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Optimize package installation layer

The package installation layer can be optimized to reduce image size:

-RUN apt update \
-        && DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install tzdata build-essential python3-opencv
+RUN apt-get update && \
+    DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get install -y --no-install-recommends \
+        tzdata \
+        build-essential \
+        python3-opencv && \
+    apt-get clean && \
+    rm -rf /var/lib/apt/lists/*
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
RUN apt update \
&& DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install tzdata build-essential python3-opencv
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get install -y --no-install-recommends \
tzdata \
build-essential \
python3-opencv && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

Comment on lines 6 to 7
WORKDIR /app
COPY . /app
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Optimize file copying strategy

The current COPY command copies all files including potentially unnecessary ones.

  1. Add appropriate entries to .dockerignore to exclude unnecessary files
  2. Consider a multi-stage build pattern
  3. Copy only required files:
-COPY . /app
+COPY conda.yaml docker_prepare.py ./
+COPY src/ ./src/

Committable suggestion was skipped due to low confidence.

Makefile Outdated
Comment on lines 1 to 5
.PHONY: default

default:
@echo Please use other targets

Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance the default target's help message.

While having a default target is good practice, consider making it more helpful by listing available targets and their descriptions.

 .PHONY: default
 
 default:
-	@echo Please use other targets
+	@echo "Available targets:"
+	@echo "  conda-env        - Update conda environment from conda.yaml"
+	@echo "  run-worker       - Run Celery worker for MIT tasks"
+	@echo "  prepare-models   - Prepare models for docker environment"
+	@echo "  build-image      - Build the MIT docker image"
+	@echo "  run-web-server   - Run the web server in docker"

Committable suggestion was skipped due to low confidence.

Comment on lines +9 to +10
run-worker:
conda run -n mit-py311 --no-capture-output celery --app moeflow_worker worker --queues mit --loglevel=debug --concurrency=1
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider making worker configuration more flexible.

The worker configuration has several hard-coded values that could benefit from being configurable:

  • Concurrency level is fixed at 1
  • Queue name is hard-coded
  • Log level is fixed at debug
 run-worker:
-	conda run -n mit-py311 --no-capture-output celery --app moeflow_worker worker --queues mit --loglevel=debug --concurrency=1
+	conda run -n mit-py311 --no-capture-output celery \
+		--app moeflow_worker \
+		worker \
+		--queues $${CELERY_QUEUE:-mit} \
+		--loglevel=$${LOG_LEVEL:-info} \
+		--concurrency=$${WORKER_CONCURRENCY:-1}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
run-worker:
conda run -n mit-py311 --no-capture-output celery --app moeflow_worker worker --queues mit --loglevel=debug --concurrency=1
run-worker:
conda run -n mit-py311 --no-capture-output celery \
--app moeflow_worker \
worker \
--queues $${CELERY_QUEUE:-mit} \
--loglevel=$${LOG_LEVEL:-info} \
--concurrency=$${WORKER_CONCURRENCY:-1}


def to_json(value: object) -> Any:
"""
:return: a json-serizable deep clone of `value`
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Correct typo in docstring: 'json-serizable' → 'json-serializable'

There's a typo in the docstring of the to_json function. Fixing it will improve code documentation clarity.

Apply this diff to correct the typo:

-    :return: a json-serizable deep clone of `value`
+    :return: a json-serializable deep clone of `value`
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
:return: a json-serizable deep clone of `value`
:return: a json-serializable deep clone of `value`

Comment on lines 55 to 58
elif isinstance(o, list):
return o
elif isinstance(o, str):
return o
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Combine similar isinstance checks to streamline the code

The isinstance checks for list and str can be combined to simplify the conditional statements.

Apply this diff to merge the checks:

-        elif isinstance(o, list):
-            return o
-        elif isinstance(o, str):
-            return o
+        elif isinstance(o, (list, str)):
+            return o
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
elif isinstance(o, list):
return o
elif isinstance(o, str):
return o
elif isinstance(o, (list, str)):
return o
🧰 Tools
🪛 Ruff

55-58: Combine if branches using logical or operator

Combine if branches

(SIM114)

Comment on lines 103 to 106
lambda r: len(r.text) > min_text_length and utils_generic.is_valuable_text(r.text),
text_blocks_all)

return to_json(text_blocks)
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Convert filter object to list before serialization

The filter object in text_blocks should be converted to a list before passing it to to_json for serialization. This ensures compatibility and prevents potential issues during JSON encoding.

Apply this diff to convert the filter object:

-    return to_json(text_blocks)
+    return to_json(list(text_blocks))
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
lambda r: len(r.text) > min_text_length and utils_generic.is_valuable_text(r.text),
text_blocks_all)
return to_json(text_blocks)
lambda r: len(r.text) > min_text_length and utils_generic.is_valuable_text(r.text),
text_blocks_all)
return to_json(list(text_blocks))

'prob': o.prob,
'textlines': self.default(o.textlines),
}
elif isinstance(o, filter) or isinstance(o, tuple):
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Simplify multiple isinstance checks into a single call

To improve code readability and efficiency, you can merge the multiple isinstance checks for o.

Apply this diff to simplify the check:

-        elif isinstance(o, filter) or isinstance(o, tuple):
+        elif isinstance(o, (filter, tuple)):
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
elif isinstance(o, filter) or isinstance(o, tuple):
elif isinstance(o, (filter, tuple)):
🧰 Tools
🪛 Ruff

53-53: Multiple isinstance calls for o, merge into a single call

Merge isinstance calls for o

(SIM101)

@@ -488,7 +493,7 @@ async def _run_detection(self, ctx: Context):
self.device, self.verbose)

async def _run_ocr(self, ctx: Context):
textlines = await dispatch_ocr(ctx.ocr, ctx.img_rgb, ctx.textlines, ctx, self.device, self.verbose)
textlines: list[Quadrilateral] = await dispatch_ocr(ctx.ocr, ctx.img_rgb, ctx.textlines, ctx, self.device, self.verbose)
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ensure Python version compatibility with type hints

The use of type hinting syntax list[Quadrilateral] is only supported in Python 3.9 and above. If the codebase needs to maintain compatibility with earlier Python versions (3.8 or below), consider importing List from the typing module and using List[Quadrilateral] instead.

Modify the type hint to maintain compatibility:

-from .utils.generic import Quadrilateral
+from typing import List
 from .utils.generic import Quadrilateral

-textlines: list[Quadrilateral] = await dispatch_ocr(...)
+textlines: List[Quadrilateral] = await dispatch_ocr(...)

Committable suggestion was skipped due to low confidence.

@jokester jokester changed the base branch from main to fix-dep-fails December 1, 2024 08:52
@jokester jokester changed the base branch from fix-dep-fails to main December 1, 2024 08:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants