Files
rasahq--rasa/tests/test_memory_leak.py
wehub-resource-sync dc6079821b
CI Github Actions / Run Tests (push) Waiting to run
Automatic PR Merger / mergepal (push) Waiting to run
Docs Tests / Check for file changes (push) Waiting to run
Docs Tests / Test Documentation (push) Blocked by required conditions
Docs Tests / Documentation Linting Checks (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-performance) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-policies) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-cli) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-core-featurizers) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-full-model-training) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-nlu-featurizers) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-performance) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-policies) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-cli) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-core-featurizers) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-full-model-training) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-nlu-featurizers) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-nlu-predictors) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-other-unit-tests) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-performance) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.9, test-policies) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.10, test-cli) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.10, test-core-featurizers) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.10, test-full-model-training) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.10, test-nlu-featurizers) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.10, test-nlu-predictors) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.10, test-other-unit-tests) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.10, test-performance) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.10, test-policies) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.8, test-cli) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.8, test-core-featurizers) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-nlu-predictors) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.8, test-other-unit-tests) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.8, test-full-model-training) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.8, test-nlu-featurizers) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.8, test-nlu-predictors) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.8, test-other-unit-tests) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.8, test-performance) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.8, test-policies) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.9, test-cli) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.9, test-core-featurizers) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.9, test-full-model-training) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.9, test-nlu-featurizers) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.9, test-nlu-predictors) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.9, test-other-unit-tests) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.9, test-performance) (push) Blocked by required conditions
Continuous Integration / Run Tests (windows-2022, 3.9, test-policies) (push) Blocked by required conditions
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.10) (push) Blocked by required conditions
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.8) (push) Blocked by required conditions
Continuous Integration / Run Flaky Tests (ubuntu-24.04, 3.9) (push) Blocked by required conditions
Continuous Integration / Run Flaky Tests (windows-2022, 3.10) (push) Blocked by required conditions
Continuous Integration / Run Flaky Tests (windows-2022, 3.8) (push) Blocked by required conditions
Continuous Integration / Run Flaky Tests (windows-2022, 3.9) (push) Blocked by required conditions
Continuous Integration / Check for file changes (push) Waiting to run
Continuous Integration / Wait for docs tests (push) Blocked by required conditions
Continuous Integration / Code Quality (push) Blocked by required conditions
Continuous Integration / Check for changelog (push) Waiting to run
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-cli) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-core-featurizers) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-full-model-training) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-nlu-featurizers) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-nlu-predictors) (push) Blocked by required conditions
Continuous Integration / Run Tests (ubuntu-24.04, 3.10, test-other-unit-tests) (push) Blocked by required conditions
Continuous Integration / Upload coverage reports to codeclimate (push) Blocked by required conditions
Continuous Integration / Run Non-Sequential Integration Tests (push) Blocked by required conditions
Continuous Integration / Run Broker Integration Tests (push) Blocked by required conditions
Continuous Integration / Run Sequential Integration Tests (push) Blocked by required conditions
Continuous Integration / Build Docker base images and setup environment (push) Waiting to run
Continuous Integration / Build Docker (default) (push) Blocked by required conditions
Continuous Integration / Build Docker (full) (push) Blocked by required conditions
Continuous Integration / Build Docker (mitie-en) (push) Blocked by required conditions
Continuous Integration / Build Docker (spacy-de) (push) Blocked by required conditions
Continuous Integration / Build Docker (spacy-en) (push) Blocked by required conditions
Continuous Integration / Build Docker (spacy-it) (push) Blocked by required conditions
Continuous Integration / Deploy to PyPI (push) Blocked by required conditions
Continuous Integration / Notify Slack & Publish Release Notes (push) Blocked by required conditions
Publish Documentation / Evaluate release tag (push) Waiting to run
Publish Documentation / Prebuild Docs (push) Blocked by required conditions
Publish Documentation / Preview Docs (push) Blocked by required conditions
Publish Documentation / Check for file changes (push) Waiting to run
Publish Documentation / Publish Docs (push) Waiting to run
Semgrep / Semgrep Workflow Security Scan (push) Waiting to run
chore: import upstream snapshot with attribution
2026-07-13 13:24:47 +08:00

229 lines
7.2 KiB
Python

import abc
import json
import subprocess
import sys
import time
from pathlib import Path
from typing import Text, List, Tuple, Optional, Union
import memory_profiler
import psutil
import pytest
import rasa
import rasa.shared.utils.io
from rasa.utils.common import TempDirectoryPath, get_temp_dir_name
PROFILING_INTERVAL = 0.1
# Enable this to plot the results locally
WRITE_RESULTS_TO_DISK = False
def _custom_default_config(
tmp_path: Union[Path, Text], epochs: int, max_history: Optional[int] = -1
) -> Text:
# Override default config to use custom amount of epochs
default_config = Path("rasa", "shared", "importers", "default_config.yml")
config = rasa.shared.utils.io.read_yaml_file(default_config)
for model_part, items in config.items():
for item in items:
if "epochs" in item:
item["epochs"] = epochs
if "max_history" in item and max_history != -1:
item["max_history"] = None
config_for_test = Path(tmp_path) / "test_config.yml"
rasa.shared.utils.io.write_yaml(config, config_for_test)
return str(config_for_test)
class MemoryLeakTest(abc.ABC):
"""Generic template for memory leak tests."""
@property
def max_memory_threshold_mb(self) -> float:
return 1000
@pytest.fixture
@abc.abstractmethod
def name_for_dumped_files(self) -> Text:
raise NotImplementedError
@abc.abstractmethod
def function_to_profile(self) -> None:
raise NotImplementedError
@pytest.mark.timeout(720, func_only=True)
def test_for_memory_leak(self, name_for_dumped_files: Text, tmp_path: Path) -> None:
# Run as separate process to avoid other things affecting the memory usage.
# Unfortunately `memory-profiler` doesn't work properly with
# `multiprocessing.Process` as it can't handle the process exit
process = subprocess.Popen(
[
sys.executable,
"-c",
(
f"from {__name__} import {self.__class__.__name__}; "
f"t = {self.__class__.__name__}();"
f"t.function_to_profile()"
),
],
# Force TensorFlow to use CPU so we can track the memory usage
env={"CUDA_VISIBLE_DEVICES": "-1"},
)
# Wait until process is running to avoid race conditions with the memory
# profiling
while not psutil.pid_exists(process.pid):
time.sleep(0.01)
results = memory_profiler.memory_usage(
process, interval=PROFILING_INTERVAL, include_children=True, timestamps=True
)
# `memory-profiler` sometimes adds `None` values at the end which we don't need
results = [
memory_timestamp
for memory_timestamp in results
if memory_timestamp is not None
]
if WRITE_RESULTS_TO_DISK:
self._write_results(name_for_dumped_files, results)
max_memory_usage = max(results, key=lambda memory_time: memory_time[0])[0]
assert max_memory_usage < self.max_memory_threshold_mb
@staticmethod
def _write_results(base_name: Text, results: List[Tuple[float, float]]) -> None:
mprof_plot = Path(f"{base_name}_plot.txt")
mprof_results = Path(f"{base_name}_raw.json")
# plot this via `mprof plot mprof_result.txt`
with open(mprof_plot, "w") as f:
for memory, timestamp in results:
f.write(f"MEM {memory:.6f} {timestamp:.4f}\n")
# dump result as json to be able analyze them without re-running the test
with open(mprof_results, "w") as f:
f.write(json.dumps(results))
class TestNLULeakManyEpochs(MemoryLeakTest):
"""Tests for memory leaks in NLU components when training with many epochs."""
@property
def epochs(self) -> int:
return 30
@property
def max_memory_threshold_mb(self) -> float:
return 2200
def function_to_profile(self) -> None:
import rasa.model_training
with TempDirectoryPath(get_temp_dir_name()) as temp_dir:
rasa.model_training.train_nlu(
_custom_default_config(temp_dir, epochs=self.epochs),
Path("data", "test_nlu_no_responses", "sara_nlu_data.yml"),
output=temp_dir,
)
@pytest.fixture()
def name_for_dumped_files(self) -> Text:
return (
f"memory_usage_rasa_nlu_{rasa.__version__}_"
f"epochs{self.epochs}_training_runs1"
)
class TestCoreLeakManyEpochs(MemoryLeakTest):
"""Tests for memory leaks in Core policies when training with many epochs."""
@property
def epochs(self) -> int:
return 200
@property
def max_memory_threshold_mb(self) -> float:
return 2000
def function_to_profile(self) -> None:
import rasa.model_training
with TempDirectoryPath(get_temp_dir_name()) as temp_dir:
rasa.model_training.train_core(
"data/test_domains/default_with_slots.yml",
_custom_default_config(temp_dir, epochs=self.epochs, max_history=None),
"data/test_yaml_stories/stories_defaultdomain.yml",
output=temp_dir,
additional_arguments={"augmentation_factor": 20},
)
@pytest.fixture()
def name_for_dumped_files(self) -> Text:
return (
f"memory_usage_rasa_core_{rasa.__version__}_"
f"epochs{self.epochs}_training_runs1"
)
class TestCRFDenseFeaturesLeak(MemoryLeakTest):
"""Tests for memory leaks in NLU the CRF when using dense features."""
@property
def epochs(self) -> int:
return 1
@property
def max_memory_threshold_mb(self) -> float:
return 1600
def function_to_profile(self) -> None:
import rasa.model_training
config = {
"pipeline": [
{"name": "SpacyNLP"},
{"name": "SpacyTokenizer"},
{"name": "SpacyFeaturizer"},
{
"name": "CRFEntityExtractor",
"features": [
["pos", "pos2"],
[
"bias",
"prefix5",
"prefix2",
"suffix5",
"suffix3",
"suffix2",
"pos",
"pos2",
"digit",
"text_dense_features",
],
["pos", "pos2"],
],
},
]
}
with TempDirectoryPath(get_temp_dir_name()) as temp_dir:
config_for_test = Path(temp_dir) / "test_config.yml"
rasa.shared.utils.io.write_yaml(config, config_for_test)
rasa.model_training.train_nlu(
str(config_for_test),
str(Path("data", "test_nlu_no_responses", "sara_nlu_data.yml")),
output=temp_dir,
)
@pytest.fixture()
def name_for_dumped_files(self) -> Text:
return f"memory_usage_rasa_nlu_crf_dense_{rasa.__version__}_"