Skip to content

Commit 2831aa9

Browse files
authored
test: Load new model version should not reload loaded existing model … (#7553)
1 parent fc359c7 commit 2831aa9

File tree

2 files changed

+162
-0
lines changed

2 files changed

+162
-0
lines changed

qa/L0_lifecycle/lifecycle_test.py

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3493,6 +3493,133 @@ def test_delete_custom_config(self):
34933493
except Exception as ex:
34943494
self.assertTrue(False, "unexpected error {}".format(ex))
34953495

3496+
def test_load_new_model_version(self):
3497+
model_name = "identity_fp32"
3498+
client = self._get_client(use_grpc=True)
3499+
3500+
# version 1 and 2 are already loaded
3501+
# version 3 is in the model directory but not loaded
3502+
# version 4 does not exist anywhere
3503+
self.assertTrue(client.is_model_ready(model_name, "1"))
3504+
self.assertTrue(client.is_model_ready(model_name, "2"))
3505+
self.assertFalse(client.is_model_ready(model_name, "3"))
3506+
self.assertFalse(client.is_model_ready(model_name, "4"))
3507+
with open(os.environ["SERVER_LOG"]) as f:
3508+
server_log = f.read()
3509+
self.assertEqual(server_log.count("[PB model] Loading version 1"), 1)
3510+
self.assertEqual(server_log.count("[PB model] Loading version 2"), 1)
3511+
self.assertEqual(server_log.count("[PB model] Loading version 3"), 0)
3512+
self.assertEqual(server_log.count("[PB model] Loading version 4"), 0)
3513+
self.assertEqual(server_log.count("successfully loaded 'identity_fp32'"), 1)
3514+
3515+
# update version 2 model file
3516+
Path(os.path.join("models", model_name, "2", "model.py")).touch()
3517+
# add version 4 model file
3518+
src_path = os.path.join("models", model_name, "3")
3519+
dst_path = os.path.join("models", model_name, "4")
3520+
shutil.copytree(src_path, dst_path)
3521+
# update model config to load version 1 to 4
3522+
config_path = os.path.join("models", model_name, "config.pbtxt")
3523+
with open(config_path, mode="r+", encoding="utf-8", errors="strict") as f:
3524+
config = f.read()
3525+
config = config.replace(
3526+
"version_policy: { specific: { versions: [1, 2] } }",
3527+
"version_policy: { specific: { versions: [1, 2, 3, 4] } }",
3528+
)
3529+
f.truncate(0)
3530+
f.seek(0)
3531+
f.write(config)
3532+
# reload the model
3533+
client.load_model(model_name)
3534+
3535+
# version 1 is unmodified so it should not be reloaded
3536+
# version 2 is modified so it should be reloaded
3537+
# version 3 model file existed but not loaded so it should be loaded
3538+
# version 4 is a new version so it should be loaded
3539+
self.assertTrue(client.is_model_ready(model_name, "1"))
3540+
self.assertTrue(client.is_model_ready(model_name, "2"))
3541+
self.assertTrue(client.is_model_ready(model_name, "3"))
3542+
self.assertTrue(client.is_model_ready(model_name, "4"))
3543+
with open(os.environ["SERVER_LOG"]) as f:
3544+
server_log = f.read()
3545+
self.assertEqual(server_log.count("[PB model] Loading version 1"), 1)
3546+
self.assertEqual(server_log.count("[PB model] Loading version 2"), 2)
3547+
self.assertEqual(server_log.count("[PB model] Loading version 3"), 1)
3548+
self.assertEqual(server_log.count("[PB model] Loading version 4"), 1)
3549+
self.assertEqual(server_log.count("successfully loaded 'identity_fp32'"), 2)
3550+
3551+
# simulate a dependency change to all versions
3552+
Path(os.path.join("models", model_name, "dummy_dependency.py")).touch()
3553+
# reload the model
3554+
client.load_model(model_name)
3555+
3556+
# all 4 versions should be reloaded
3557+
self.assertTrue(client.is_model_ready(model_name, "1"))
3558+
self.assertTrue(client.is_model_ready(model_name, "2"))
3559+
self.assertTrue(client.is_model_ready(model_name, "3"))
3560+
self.assertTrue(client.is_model_ready(model_name, "4"))
3561+
with open(os.environ["SERVER_LOG"]) as f:
3562+
server_log = f.read()
3563+
self.assertEqual(server_log.count("[PB model] Loading version 1"), 2)
3564+
self.assertEqual(server_log.count("[PB model] Loading version 2"), 3)
3565+
self.assertEqual(server_log.count("[PB model] Loading version 3"), 2)
3566+
self.assertEqual(server_log.count("[PB model] Loading version 4"), 2)
3567+
self.assertEqual(server_log.count("successfully loaded 'identity_fp32'"), 3)
3568+
3569+
# update model config to only load version 4
3570+
config_path = os.path.join("models", model_name, "config.pbtxt")
3571+
with open(config_path, mode="r+", encoding="utf-8", errors="strict") as f:
3572+
config = f.read()
3573+
config = config.replace(
3574+
"version_policy: { specific: { versions: [1, 2, 3, 4] } }",
3575+
"version_policy: { specific: { versions: [4] } }",
3576+
)
3577+
f.truncate(0)
3578+
f.seek(0)
3579+
f.write(config)
3580+
# reload the model
3581+
client.load_model(model_name)
3582+
3583+
# only version 4 should be available and no reloads should happen
3584+
self.assertFalse(client.is_model_ready(model_name, "1"))
3585+
self.assertFalse(client.is_model_ready(model_name, "2"))
3586+
self.assertFalse(client.is_model_ready(model_name, "3"))
3587+
self.assertTrue(client.is_model_ready(model_name, "4"))
3588+
with open(os.environ["SERVER_LOG"]) as f:
3589+
server_log = f.read()
3590+
self.assertEqual(server_log.count("[PB model] Loading version 1"), 2)
3591+
self.assertEqual(server_log.count("[PB model] Loading version 2"), 3)
3592+
self.assertEqual(server_log.count("[PB model] Loading version 3"), 2)
3593+
self.assertEqual(server_log.count("[PB model] Loading version 4"), 2)
3594+
self.assertEqual(server_log.count("successfully loaded 'identity_fp32'"), 4)
3595+
3596+
# update model config to load version 1 and 4
3597+
config_path = os.path.join("models", model_name, "config.pbtxt")
3598+
with open(config_path, mode="r+", encoding="utf-8", errors="strict") as f:
3599+
config = f.read()
3600+
config = config.replace(
3601+
"version_policy: { specific: { versions: [4] } }",
3602+
"version_policy: { specific: { versions: [1, 4] } }",
3603+
)
3604+
f.truncate(0)
3605+
f.seek(0)
3606+
f.write(config)
3607+
# reload the model
3608+
client.load_model(model_name)
3609+
3610+
# version 1 should be loaded and version 4 should not be reloaded
3611+
self.assertTrue(client.is_model_ready(model_name, "1"))
3612+
self.assertFalse(client.is_model_ready(model_name, "2"))
3613+
self.assertFalse(client.is_model_ready(model_name, "3"))
3614+
self.assertTrue(client.is_model_ready(model_name, "4"))
3615+
with open(os.environ["SERVER_LOG"]) as f:
3616+
server_log = f.read()
3617+
self.assertEqual(server_log.count("[PB model] Loading version 1"), 3)
3618+
self.assertEqual(server_log.count("[PB model] Loading version 2"), 3)
3619+
self.assertEqual(server_log.count("[PB model] Loading version 3"), 2)
3620+
self.assertEqual(server_log.count("[PB model] Loading version 4"), 2)
3621+
self.assertEqual(server_log.count("successfully loaded 'identity_fp32'"), 5)
3622+
34963623

34973624
if __name__ == "__main__":
34983625
unittest.main()

qa/L0_lifecycle/test.sh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,6 +2196,41 @@ set -e
21962196
kill $SERVER_PID
21972197
wait $SERVER_PID
21982198

2199+
LOG_IDX=$((LOG_IDX+1))
2200+
2201+
# LifeCycleTest.test_load_new_model_version
2202+
rm -rf models
2203+
mkdir models
2204+
cp -r ../python_models/identity_fp32 models/ && (cd models/identity_fp32 && \
2205+
echo "version_policy: { specific: { versions: [1, 2] } }" >> config.pbtxt && \
2206+
echo " def initialize(self, args):" >> model.py && \
2207+
echo " pb_utils.Logger.log_info(f'[PB model] Loading version {args[\"model_version\"]}')" >> model.py && \
2208+
mkdir 1 && cp model.py 1 && \
2209+
mkdir 2 && cp model.py 2 && \
2210+
mkdir 3 && mv model.py 3)
2211+
2212+
export PYTHONDONTWRITEBYTECODE="True"
2213+
SERVER_ARGS="--model-repository=`pwd`/models --model-control-mode=explicit --load-model=*"
2214+
SERVER_LOG="./inference_server_$LOG_IDX.log"
2215+
run_server
2216+
if [ "$SERVER_PID" == "0" ]; then
2217+
echo -e "\n***\n*** Failed to start $SERVER\n***"
2218+
cat $SERVER_LOG
2219+
exit 1
2220+
fi
2221+
2222+
set +e
2223+
SERVER_LOG=$SERVER_LOG python $LC_TEST LifeCycleTest.test_load_new_model_version >>$CLIENT_LOG 2>&1
2224+
if [ $? -ne 0 ]; then
2225+
cat $CLIENT_LOG
2226+
echo -e "\n***\n*** Test Failed\n***"
2227+
RET=1
2228+
fi
2229+
set -e
2230+
2231+
kill $SERVER_PID
2232+
wait $SERVER_PID
2233+
unset PYTHONDONTWRITEBYTECODE
21992234

22002235
if [ $RET -eq 0 ]; then
22012236
echo -e "\n***\n*** Test Passed\n***"

0 commit comments

Comments
 (0)