Skip to content

Conversation

@xunyoyo
Copy link
Contributor

@xunyoyo xunyoyo commented Nov 15, 2025

Motivation

NO.24 功能模块 fastdeploy/model_executor/models/tp_utils.py 单测补充

Modifications

add tests/model_executor/models/test_tp_utils.py

Usage or Command

tests/model_executor/test_tp_utils.py:

python -m coverage run -m unittest tests.model_executor.test_tp_utils \
&& python -m coverage report -m --include='fastdeploy/model_executor/models/tp_utils.py'

Accuracy Tests

旧覆盖

File	Stmts	Miss	Branch	BrPart	Cover(%)
fastdeploy/model_executor/models/tp_utils.py	201	170	106	0	10

tests/model_executor/models/test_tp_utils.py:

Name                                           Stmts   Miss  Cover   Missing
----------------------------------------------------------------------------
fastdeploy/model_executor/models/tp_utils.py     201     27    87%   130, 143, 160, 177, 191, 228, 248, 256-259, 278, 283, 297-3
16, 353-356, 376-382, 387, 440
----------------------------------------------------------------------------
TOTAL                                            201     27    87%

覆盖 ++143 行

Checklist

  • Add at least a tag in the PR title.
    • Tag list: [[FDConfig],[APIServer],[Engine], [Scheduler], [PD Disaggregation], [Executor], [Graph Optimization], [Speculative Decoding], [RL], [Models], [Quantization], [Loader], [OP], [KVCache], [DataProcessor], [BugFix], [Docs], [CI], [Optimization], [Feature], [Benchmark], [Others], [XPU], [HPU], [GCU], [DCU], [Iluvatar], [Metax]]
    • You can add new tags based on the PR content, but the semantics must be clear.
  • Format your code, run pre-commit before commit.
  • Add unit tests. Please write the reason in this PR if no unit tests.
  • Provide accuracy results.
  • If the current PR is submitting to the release branch, make sure the PR has been submitted to the develop branch, then cherry-pick it to the release branch with the [Cherry-Pick] PR tag.

Copilot AI review requested due to automatic review settings November 15, 2025 10:16
@paddle-bot
Copy link

paddle-bot bot commented Nov 15, 2025

Thanks for your contribution!

@paddle-bot paddle-bot bot added the contributor External developers label Nov 15, 2025
Copilot finished reviewing on behalf of xunyoyo November 15, 2025 10:18
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR adds comprehensive unit tests for the fastdeploy/model_executor/models/tp_utils.py module as part of Hackathon 9th Sprint No.24, achieving 87% test coverage. The test suite uses sophisticated stubbing techniques to test the tensor parallel utility functions in isolation without requiring the full PaddlePaddle and PaddleFormers dependencies.

Key changes:

  • Implements extensive mocking infrastructure for paddle, paddleformers, and fastdeploy dependencies
  • Tests core tensor parallel prerequisite checking, helper functions, key expansion logic, and GQA tensor operations
  • Achieves 87% code coverage with 201 statements tested (27 lines remain uncovered)

Comment on lines 1 to 3
"""Unit tests for tensor parallel utility helpers."""

from __future__ import annotations
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

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

The test file is missing the standard Apache 2.0 copyright header that is present in other test files in this repository (e.g., test_logits_processor.py and test_forward_meta_str.py). Please add the copyright header at the beginning of the file following the project's standard format.

Copilot uses AI. Check for mistakes.
def _split_or_merge_func(is_split, tensor_parallel_degree, tensor_parallel_rank, **_kwargs):
axis = -1

def _fn(weight, *, is_column=True, is_naive_2fuse=False): # pylint: disable=unused-argument
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

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

[nitpick] The pylint disable comment uses an inline format. For consistency with project standards and better maintainability, consider using the more specific format or removing unused parameters if they're truly not needed in the stub implementation.

Suggested change
def _fn(weight, *, is_column=True, is_naive_2fuse=False): # pylint: disable=unused-argument
def _fn(weight, *, is_column=True):

Copilot uses AI. Check for mistakes.
np.testing.assert_array_equal(merged, np.array([0, 1, 2, 3], dtype=np.float32))


if __name__ == "__main__": # pragma: no cover - entry point for python -m unittest
Copy link

Copilot AI Nov 15, 2025

Choose a reason for hiding this comment

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

[nitpick] The pragma comment format is inconsistent. Most test files in this codebase don't use pragma comments for the main block. Consider removing the pragma comment or ensuring it follows the project's coverage reporting conventions.

Suggested change
if __name__ == "__main__": # pragma: no cover - entry point for python -m unittest
if __name__ == "__main__":

Copilot uses AI. Check for mistakes.
@xunyoyo
Copy link
Contributor Author

xunyoyo commented Nov 17, 2025

@luotao1 @YuanRisheng
同样在 pr action 检查过程中 api 调用出现了问题,导致报错停止。

Running pytest file: tests/e2e/test_ernie_03b_pd_router_v0.py
============================= test session starts ==============================
platform linux -- Python 3.10.13, pytest-9.0.1, pluggy-1.6.0 -- /usr/local/bin/python
cachedir: .pytest_cache
rootdir: /workspace/FastDeploy/tests
configfile: cov_pytest.ini
plugins: asyncio-1.3.0, respx-0.22.0, anyio-4.9.0
asyncio: mode=strict, debug=False, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function
collecting ... collected 5 items

tests/e2e/test_ernie_03b_pd_router_v0.py::test_metrics_config Pre-test port cleanup...
Cleaning ports: [8688, 8658, 8678, 8698, 8638, 8689, 8659, 8679, 8699, 8639, 8648]
log dir clean 
model_path: /ModelData/ERNIE-4.5-0.3B-Paddle
start router...
start prefill...
start decode...
Prefill and decode servers are both online
PASSED
tests/e2e/test_ernie_03b_pd_router_v0.py::test_chat_usage_stream 🟢 接收响应中...

Decode Response: 牛顿的三大运动定律是牛顿力学的基本原理,它们是描述物体运动和力的关系的基础。以下是这三条定律的详细解释:

### 一、牛顿第一定律(惯性定律)

**定义**:牛顿第一
PASSED
tests/e2e/test_ernie_03b_pd_router_v0.py::test_chat_usage_non_stream 🟢 接收响应中...

PASSED
tests/e2e/test_ernie_03b_pd_router_v0.py::test_non_chat_usage_stream 🟢 接收响应中...

Decode Response: 

### 解答

牛顿的三大运动定律是:

1. **惯性定律**:物体保持静止或匀速直线运动状态的性质,即**惯性**。
2. **万有引力定律**:
PASSED
tests/e2e/test_ernie_03b_pd_router_v0.py::test_non_chat_usage_non_stream 🟢 接收响应中...

Decode Response: 

### 解答

牛顿的三大运动定律是:

1. **惯性定律**:物体保持静止或匀速直线运动状态的性质,即**惯性**。
2. **万有引力定律**:
PASSED
===== Post-test server cleanup... =====
Cleaning ports: [8688, 8658, 8678, 8698, 8638, 8689, 8659, 8679, 8699, 8639, 8648]
Killed process on port 8658, pid=8672
Killed process on port 8659, pid=8811
Prefill server (pid=8672) terminated
Decode server (pid=8811) terminated


/usr/local/lib/python3.10/site-packages/coverage/control.py:950: CoverageWarning: No data was collected. (no-data-collected); see https://coverage.readthedocs.io/en/7.11.3/messages.html#warning-no-data-collected
  self._warn("No data was collected.", slug="no-data-collected")
============================== 5 passed in 46.41s ==============================
Running pytest file: tests/e2e/test_ernie_03b_pd_splitwise_scheduler.py
============================= test session starts ==============================
platform linux -- Python 3.10.13, pytest-9.0.1, pluggy-1.6.0 -- /usr/local/bin/python
cachedir: .pytest_cache
rootdir: /workspace/FastDeploy/tests
configfile: cov_pytest.ini
plugins: asyncio-1.3.0, respx-0.22.0, anyio-4.9.0
asyncio: mode=strict, debug=False, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function
collecting ... collected 5 items

tests/e2e/test_ernie_03b_pd_splitwise_scheduler.py::test_metrics_config Pre-test port cleanup...
Cleaning ports: [8688, 8658, 8678, 8698, 8638, 8689, 8659, 8679, 8699, 8639, 8533]
log dir clean 
model_path: /ModelData/ERNIE-4.5-0.3B-Paddle
start redis...
start prefill...
start decode...
Prefill server is up on port 8688
Decode server is up on port 8689
PASSED
tests/e2e/test_ernie_03b_pd_splitwise_scheduler.py::test_chat_usage_stream 🟢 接收响应中...

Decode Response: 牛顿的三大运动定律是牛顿力学的基本原理,它们是描述物体运动和力的关系的基础。以下是这三条定律的详细解释:

### 一、牛顿第一定律(惯性定律)

**定义**:牛顿第一
PASSED
tests/e2e/test_ernie_03b_pd_splitwise_scheduler.py::test_chat_usage_non_stream ❌ 请求超时(超过 600 秒)
FAILED
tests/e2e/test_ernie_03b_pd_splitwise_scheduler.py::test_non_chat_usage_stream 🟢 接收响应中...

PASSED
tests/e2e/test_ernie_03b_pd_splitwise_scheduler.py::test_non_chat_usage_non_stream 🟢 接收响应中...

PASSED
===== Post-test server cleanup... =====
Cleaning ports: [8688, 8658, 8678, 8698, 8638, 8689, 8659, 8679, 8699, 8639, 8533]
Killed process on port 8658, pid=10328
Killed process on port 8658, pid=10404
Prefill server (pid=10328) terminated
Decode server (pid=10404) terminated


=================================== FAILURES ===================================
__________________________ test_chat_usage_non_stream __________________________

api_url = ('http://0.0.0.0:8688/v1/chat/completions', 'http://0.0.0.0:8689/v1/chat/completions')

    def test_chat_usage_non_stream(api_url):
        """测试非流式chat usage"""
        payload = {
            "model": "default",
            "temperature": 0,
            "top_p": 0,
            "seed": 33,
            "messages": [
                {"role": "system", "content": "You are a helpful assistant."},
                {"role": "user", "content": "牛顿的三大运动定律是什么?"},
            ],
            "max_tokens": 50,
            "stream": False,
            "metadata": {"min_tokens": 10},
        }
    
        p_url, d_url = api_url
>       response = send_request(url=p_url, payload=payload).json()
E       AttributeError: 'NoneType' object has no attribute 'json'

tests/e2e/test_ernie_03b_pd_splitwise_scheduler.py:366: AttributeError

我的已通过

Running pytest file: tests/model_executor/test_tp_utils.py
============================= test session starts ==============================
platform linux -- Python 3.10.13, pytest-9.0.1, pluggy-1.6.0 -- /usr/local/bin/python
cachedir: .pytest_cache
rootdir: /workspace/FastDeploy/tests
configfile: cov_pytest.ini
plugins: asyncio-1.3.0, respx-0.22.0, anyio-4.9.0
asyncio: mode=strict, debug=False, asyncio_default_fixture_loop_scope=None, asyncio_default_test_loop_scope=function
collecting ... collected 26 items

tests/model_executor/test_tp_utils.py::CheckTensorParallelPrerequisitesTest::test_inconsistent_tensor_parallel_keys_logs_error PASSED
tests/model_executor/test_tp_utils.py::CheckTensorParallelPrerequisitesTest::test_missing_tensor_parallel_map_logs_error PASSED
tests/model_executor/test_tp_utils.py::CheckTensorParallelPrerequisitesTest::test_tensor_parallel_disabled_noop PASSED
tests/model_executor/test_tp_utils.py::CheckTensorParallelPrerequisitesTest::test_tensor_parallel_mappings_populated PASSED
tests/model_executor/test_tp_utils.py::HelperFunctionTest::test_extract_placeholders PASSED
tests/model_executor/test_tp_utils.py::HelperFunctionTest::test_extract_prefix_variants PASSED
tests/model_executor/test_tp_utils.py::HelperFunctionTest::test_has_placeholders PASSED
tests/model_executor/test_tp_utils.py::HelperFunctionTest::test_has_prefix PASSED
tests/model_executor/test_tp_utils.py::HelperFunctionTest::test_safe_dict_preserves_unknown PASSED
tests/model_executor/test_tp_utils.py::HelperFunctionTest::test_update_final_actions_formats_keys PASSED
tests/model_executor/test_tp_utils.py::BuildExpandedKeysTest::test_ffn_layer_id_requires_start PASSED
tests/model_executor/test_tp_utils.py::BuildExpandedKeysTest::test_invalid_placeholder_raises PASSED
tests/model_executor/test_tp_utils.py::BuildExpandedKeysTest::test_layer_id_placeholder PASSED
tests/model_executor/test_tp_utils.py::BuildExpandedKeysTest::test_moe_layer_and_expert_id PASSED
tests/model_executor/test_tp_utils.py::BuildExpandedKeysTest::test_moe_layer_and_image_expert_id PASSED
tests/model_executor/test_tp_utils.py::BuildExpandedKeysTest::test_moe_layer_and_text_expert_id PASSED
tests/model_executor/test_tp_utils.py::BuildExpandedKeysTest::test_moe_layer_only PASSED
tests/model_executor/test_tp_utils.py::BuildExpandedKeysTest::test_no_placeholder_keys_pass_through PASSED
tests/model_executor/test_tp_utils.py::GQATensorOpsTest::test_gqa_merge_reconstructs_weights PASSED
tests/model_executor/test_tp_utils.py::GQATensorOpsTest::test_gqa_split_on_matrix_rows PASSED
tests/model_executor/test_tp_utils.py::GQATensorOpsTest::test_gqa_split_returns_all_partitions PASSED
tests/model_executor/test_tp_utils.py::GQATensorOpsTest::test_gqa_split_with_rank_and_repeat_kv PASSED
tests/model_executor/test_tp_utils.py::GQATensorOpsTest::test_split_or_merge_func_v1_default_path PASSED
tests/model_executor/test_tp_utils.py::GQATensorOpsTest::test_split_or_merge_func_v1_gqa_path PASSED
tests/model_executor/test_tp_utils.py::GQATensorOpsTest::test_split_or_merge_func_v1_row_bias PASSED
tests/model_executor/test_tp_utils.py::GQATensorOpsTest::test_split_or_merge_qkv_dispatch PASSED

============================== 26 passed in 0.16s ==============================

Copy link
Collaborator

@YuanRisheng YuanRisheng left a comment

Choose a reason for hiding this comment

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

把减少的miss行数在描述里补充一下,另外把ai的review建议都改一下

@codecov-commenter
Copy link

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (develop@95b3931). Learn more about missing BASE report.

Additional details and impacted files
@@            Coverage Diff             @@
##             develop    #5055   +/-   ##
==========================================
  Coverage           ?   58.86%           
==========================================
  Files              ?      317           
  Lines              ?    38679           
  Branches           ?     5812           
==========================================
  Hits               ?    22767           
  Misses             ?    14081           
  Partials           ?     1831           
Flag Coverage Δ
GPU 58.86% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@YuanRisheng YuanRisheng merged commit edf0d09 into PaddlePaddle:develop Nov 25, 2025
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants