Skip to content

refactor(translator): enhance prompt conversion method#637

Merged
awwaawwa merged 18 commits intoPDFMathTranslate:mainfrom
Tql-ws1:change-prompt-conversion-method
Feb 21, 2025
Merged

refactor(translator): enhance prompt conversion method#637
awwaawwa merged 18 commits intoPDFMathTranslate:mainfrom
Tql-ws1:change-prompt-conversion-method

Conversation

@Tql-ws1
Copy link
Contributor

@Tql-ws1 Tql-ws1 commented Feb 16, 2025

…hen using custom prompts.

Main Changes:
  - Replaced `eval()` with `json.loads()` to convert text into a JSON object.
  - Emphasized the occurrence of errors that prevent further execution.
    - Used `string.Template.substitute()` instead of `string.Template.safe_substitute()` to avoid unintentional use of incorrectly formatted templates.
    - Added logging information to inform users whether the custom prompt is being used effectively.
Other Changes:
  Refactor!:
    - Used `num_predict` parameter to set the output length limit for large language models in ollama.
  Perf!:
    - Removed broad and redundant exception throwing.
    - Disabled streaming output and used regular expressions to remove thought chain outputs.
  Test:
    - Added unit test cases for `OllamaTranslator`.
  Style:
    - Sorted library imports.
    - Added type hints where necessary.

Related to issue #636.
@awwaawwa awwaawwa linked an issue Feb 16, 2025 that may be closed by this pull request
4 tasks
@awwaawwa awwaawwa marked this pull request as draft February 16, 2025 16:44
@awwaawwa
Copy link
Collaborator

I have converted this PR to draft status. Please mark it as Ready after the work is completed.

@awwaawwa
Copy link
Collaborator

_remove_cot_content can use re.sub and ^<think>.+?</think>

@Tql-ws1
Copy link
Contributor Author

Tql-ws1 commented Feb 16, 2025

_remove_cot_content can use re.sub and ^<think>.+?</think>

Good idea!

@awwaawwa awwaawwa linked an issue Feb 16, 2025 that may be closed by this pull request
@hellofinch
Copy link
Collaborator

def do_translate(self, text):
        for model in self.model.split(";"):
            try:
                response = self.client.chat(
                    model=self.model,
                    options=self.options,
                    messages=self.prompt(text, self.prompttext),
                )
                response = response["message"]["content"].strip()
                if (
                    "deepseek-r1" in model
                    and "<think>" in response["message"]["content"].strip()
                    and "</think>" in response["message"]["content"].strip()
                ):
                    response = re.sub(
                        r"^<think>.+?</think>",
                        "",
                        response["message"]["content"].strip(),
                    )
                return response
            except Exception as e:
                print(e)
        raise Exception("All models failed")

Here for you.
Remember to test API, CLI, and WebUI to make sure the custom prompt is working well.
Custom prompt use Templete. Sometime None check will pass.

@Tql-ws1
Copy link
Contributor Author

Tql-ws1 commented Feb 17, 2025

Completed. However, json.loads() can only parse and will not perform implicit conversion for invalid content. Therefore, the prompts users provide in the future need to be in valid JSON format.

@Tql-ws1
Copy link
Contributor Author

Tql-ws1 commented Feb 17, 2025

And you, @hellofinch! If you wanted to solve this issue, you should have raised it four days ago and also initiated a pull request at the same time, rather than waiting until today. This way, others would have one less merge conflict to handle and wouldn't have to clean up the mess you left behind!

@Tql-ws1 Tql-ws1 marked this pull request as ready for review February 17, 2025 12:21
@awwaawwa
Copy link
Collaborator

awwaawwa commented Feb 17, 2025

Please pass all CI checks, thank you!

However, it might be because the format was changed recently but CI wasn't updated........

@awwaawwa
Copy link
Collaborator

awwaawwa commented Feb 17, 2025

And you, @hellofinch! If you wanted to solve this issue, you should have raised it four days ago and also initiated a pull request at the same time, rather than waiting until today. This way, others would have one less merge conflict to handle and wouldn't have to clean up the mess you left behind!

Thank you for your feedback. We understand that merge conflicts can create additional workload. At the same time, we want to thank @hellofinch for their efforts and voluntary contributions. This is an open-source project, and everyone's time and energy are valuable - we're grateful for all participation.

To better avoid similar conflicts in the future, everyone can consider raising issues and discussing them early when problems are discovered, and plan solutions in advance. If you have any suggestions or better practices to make collaboration smoother, we very much welcome your sharing!

Once again, thank you to every contributor for your dedication in making this project better together!

@awwaawwa awwaawwa self-requested a review February 17, 2025 14:28
@Tql-ws1
Copy link
Contributor Author

Tql-ws1 commented Feb 17, 2025

Undoubtedly, @hellofinch's contributions are certainly commendable. But, code reviewers! Could you please help? How did something like using eval() to convert template strings into ChatRequest messages happen? When I checked the blame for this code, I also noticed several poor changes related to @hellofinch.

When I raised issue #636 and initiated pull request #637, I wondered if @hellofinch had reviewed them. I assume they didn't, otherwise, why would they suggest more verbose and less readable code and remind me to conduct thorough testing? If you had reviewed my changes, you might not have posted such content. Interestingly, about ten minutes after posting this code, @hellofinch began submitting a related pull request, with the commit time for pdf2zh/translator.py being February 13, 2025. Merge conflicts are inevitable. Buddy, could you please take a look at what changes #637 made before submitting?

That's why I'm frustrated with @hellofinch and the reviewers who approved @hellofinch's commit. It's absurd! Making contributions is cool, but when those contributions contradict the project's direction and quality, and are accepted without refinement, they become a burden.

@Byaidu
Copy link
Member

Byaidu commented Feb 17, 2025

Undoubtedly, @hellofinch's contributions are certainly commendable. But, code reviewers! Could you please help? How did something like using eval() to convert template strings into ChatRequest messages happen? When I checked the blame for this code, I also noticed several poor changes related to @hellofinch.

When I raised issue #636 and initiated pull request #637, I wondered if @hellofinch had reviewed them. I assume they didn't, otherwise, why would they suggest more verbose and less readable code and remind me to conduct thorough testing? If you had reviewed my changes, you might not have posted such content. Interestingly, about ten minutes after posting this code, @hellofinch began submitting a related pull request, with the commit time for pdf2zh/translator.py being February 13, 2025. Merge conflicts are inevitable. Buddy, could you please take a look at what changes #637 made before submitting?

That's why I'm frustrated with @hellofinch and the reviewers who approved @hellofinch's commit. It's absurd! Making contributions is cool, but when those contributions contradict the project's direction and quality, and are accepted without refinement, they become a burden.

Apologies for my mistake in reviewing, and thank you for pointing it out. We will revert the erroneous commits and work on improving the maintainability of the codebase.

@hellofinch
Copy link
Collaborator

GOOD!

@awwaawwa awwaawwa added this to the v1.9.1 milestone Feb 18, 2025
Copy link
Collaborator

@awwaawwa awwaawwa left a comment

Choose a reason for hiding this comment

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

Could you revise the test when you have time?

@awwaawwa awwaawwa requested review from awwaawwa and removed request for awwaawwa February 18, 2025 16:08
Copy link
Collaborator

@awwaawwa awwaawwa left a comment

Choose a reason for hiding this comment

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

@hellofinch when you have time please help test the cli etc.

I've tested the webui, it works fine.

CleanShot 2025-02-19 at 00 03 01@2x

@Tql-ws1
Copy link
Contributor Author

Tql-ws1 commented Feb 18, 2025

Should we mock self.client.chat here and then do the testing?

@awwaawwa Thank you for pointing out that "the object being mocked should be more concrete" and for helping me further improve the unit tests of OllamaTranslator.

In addition, using ast.literal_eval can safely evaluate an expression node or a string containing only a Python literal or container display. The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans, None and Ellipsis.

ast.literal_eval() attempts to evaluate the text, but it cannot convert risky text into pure text. You can try adding some expressions in the prompt, such as a2-a1, or inserting a single quote, and see what happens. I believe user input should be normalized rather than compromised, which would otherwise leave hidden issues and result in an endless stream of parsing errors and strange exceptions.

Here you can catch errors and send out user-friendly error messages

I reviewed your changes here, and I think we should not add any exception handling statements except for those expected exceptions. I raised #636 because when an error occurred, it did not provide specific exception information, making it difficult to pinpoint the root cause. You can try modifying the code in prompt() locally; there is only one line, raise, and see if the program halts.

@Tql-ws1 Tql-ws1 requested a review from awwaawwa February 18, 2025 17:31
@awwaawwa
Copy link
Collaborator

awwaawwa commented Feb 19, 2025

@Tql-ws1 The exception handling is a problem with the current program architecture. I plan to solve it through pdf2zh 2.0. The current solution is a workaround that can help reduce customer service pressure.

As for ast.literal_eval(), I think it can be completely removed. Specifically: we can write all prompts into the User prompt, and then just use template strings.

Additionally, this modification can improve compatibility with models like o1/r1, since these models cannot set system prompts.

@Tql-ws1
Copy link
Contributor Author

Tql-ws1 commented Feb 19, 2025

As for ast.literal_eval(), I think it can be completely removed. Specifically: we can write all prompts into the User prompt, and then just use template strings.

Additionally, this modification can improve compatibility with models like o1/r1, since these models cannot set system prompts.

Using template substitution alone can indeed avoid parsing issues caused by formatting, but what about models that rely on system prompts to constrain their behavior? This might reduce translation quality. How about considering releasing a nightly version to crowdtest and compare the effects before and after removing the system prompt?

@awwaawwa
Copy link
Collaborator

Unfortunately, the current release CI doesn't handle nightly builds very well... However, I hope to improve this in #645.

After improving the release CI, releasing will become much easier, so it should be safe to include this change directly in the official version. If there are many reports of translation quality degradation, we can revert this change.

As for ast.literal_eval(), I think it can be completely removed. Specifically: we can write all prompts into the User prompt, and then just use template strings.
Additionally, this modification can improve compatibility with models like o1/r1, since these models cannot set system prompts.

Using template substitution alone can indeed avoid parsing issues caused by formatting, but what about models that rely on system prompts to constrain their behavior? This might reduce translation quality. How about considering releasing a nightly version to crowdtest and compare the effects before and after removing the system prompt?

@Tql-ws1
Copy link
Contributor Author

Tql-ws1 commented Feb 19, 2025

Okay, understood. Are there any other areas that need improvement regarding this submission? If not, I think I've covered everything I needed to do.

@awwaawwa
Copy link
Collaborator

Okay, understood. Are there any other areas that need improvement regarding this submission? If not, I think I've covered everything I needed to do.

Next, I'll wait for @hellofinch to help test the API and CLI custom prompt functionality. After his testing, I will merge this PR.

@awwaawwa
Copy link
Collaborator

@Tql-ws1 I just remembered that https://github.com/Byaidu/PDFMathTranslate/blob/main/docs/ADVANCED.md#custom-prompt this file needs some modifications. For example, this prompt I used for testing before:

You are a professional,authentic machine translation engine. 如果目标语言为中文,你需要翻译成文言文。 Translate the following markdown source text to ${lang_out}. Keep the formula notation {{v*}} unchanged. Output translation directly without any additional text.\nSource Text: ${text}\nTranslated Text:

@hellofinch
Copy link
Collaborator

CLI and WebUI work fine for me. @awwaawwa
API never support prompt. I will try fix API part.

@awwaawwa
Copy link
Collaborator

Thank you for your contribution. According to https://funstory-ai.github.io/BabelDOC/CONTRIBUTOR_REWARD/ , you can apply for a monthly membership redemption code for Immersive Translate.

@awwaawwa awwaawwa changed the title Change prompt conversion method refactor(translator): enhance prompt conversion method Feb 21, 2025
@awwaawwa awwaawwa merged commit ecb9218 into PDFMathTranslate:main Feb 21, 2025
2 checks passed
@hellofinch
Copy link
Collaborator

Nice work! API works good now! Very Well!!

@Tql-ws1 Tql-ws1 deleted the change-prompt-conversion-method branch February 27, 2025 03:04
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.

An error occurred when using custom prompt template feat(translator): remove LLM <think>xxx</think>

4 participants