50 lines
4.0 KiB
Python
50 lines
4.0 KiB
Python
import unittest
|
|
from unittest.mock import patch,Mock
|
|
from catalog import capabilities,file_role
|
|
from profiles import chat_parameters
|
|
from test_inference import WorkerTests
|
|
|
|
class CapabilitiesTests(unittest.TestCase):
|
|
def test_unknown_is_not_negative_or_name_guess(self):
|
|
self.assertEqual(capabilities({'id':'org/vision-tools'})['vision'],'Unbekannt')
|
|
self.assertEqual(capabilities({'tags':['function-calling']})['tools'],'Hinweis laut Hub')
|
|
self.assertEqual(capabilities({'pipeline_tag':'image-text-to-text'})['vision'],'Hinweis laut Hub')
|
|
self.assertEqual(capabilities({'siblings':[{'rfilename':'mmproj-model.gguf'}]})['vision'],'Projektordatei vorhanden')
|
|
def test_projector_is_not_standalone_or_text_encoder(self):
|
|
self.assertEqual(file_role('mmproj-qwen3vl.gguf')['role'],'vision_projector');self.assertFalse(file_role('mmproj-qwen3vl.gguf')['profile_eligible'])
|
|
def test_reserve_validation(self):
|
|
self.assertEqual(chat_parameters({})['gpu_reserve_mode'],'auto')
|
|
for value in (-1,32769,True,1.5):
|
|
with self.assertRaises(ValueError):chat_parameters({'gpu_devices':['GPU-a'],'gpu_reserve_mode':'manual','gpu_reserve_mib':{'GPU-a':value}})
|
|
with self.assertRaises(ValueError):chat_parameters({'gpu_reserve_mode':'manual'})
|
|
def test_projector_device_validates_uuid_independently(self):
|
|
with self.assertRaises(ValueError):chat_parameters({'vision_device':'GPU-missing'})
|
|
uuid='GPU-4834d9d7-5b61-3004-1fb3-4ae49d482d4b'
|
|
self.assertEqual(chat_parameters({'vision_device':uuid})['vision_device'],uuid)
|
|
|
|
class ProjectorLaunchTests(WorkerTests):
|
|
def test_cpu_and_gpu_projector_flags_and_reserve(self):
|
|
for device in ('cpu','gpu-second'):
|
|
self.worker.stop();self.profile['parameters'].update(vision_projector='p',vision_device=device)
|
|
self.worker.catalog.entry=lambda ident:dict(id='p',file='mmproj.gguf',size=1024**3,role='vision_projector') if ident=='p' else self.entry
|
|
process=Mock();process.poll.return_value=None;http=Mock();http.getresponse.return_value.status=200
|
|
with self.patches(),patch('inference.probe',return_value=self.gpus),patch('inference.cgroup_headroom',return_value=32*1024**3),patch.object(self.worker,'_fit_command',return_value='CUDA0 9000 1000 1000\nCUDA1 2000 1000 1000\nHost 512 0 256\n'),patch('inference.subprocess.Popen',return_value=process) as launch,patch('inference.http.client.HTTPConnection',return_value=http),patch('inference.threading.Thread'):
|
|
self.worker.ensure(self.profile)
|
|
args=launch.call_args.args[0];self.assertIn('--mmproj',args)
|
|
if device=='cpu':self.assertIn('--no-mmproj-offload',args)
|
|
else:self.assertEqual(args[args.index('--mmproj-device')+1],'CUDA1');self.assertEqual(self.worker.memory_plan['gpus'][1]['required_mib'],7072)
|
|
self.worker.process=None
|
|
def test_projector_only_gpu_excluded_from_model_devices(self):
|
|
self.profile['parameters'].update(gpu_devices=['gpu-first'],split_mode='none',tensor_split=[],vision_projector='p',vision_device='gpu-second',gpu_offload='full')
|
|
self.worker.catalog.entry=lambda ident:dict(id='p',file='mmproj.gguf',size=1024**3,role='vision_projector') if ident=='p' else self.entry
|
|
process=Mock();process.poll.return_value=None;http=Mock();http.getresponse.return_value.status=200
|
|
with self.patches(),patch('inference.probe',return_value=self.gpus),patch('inference.cgroup_headroom',return_value=32*1024**3),patch.object(self.worker,'_fit_command',return_value='CUDA0 9000 1000 1000\nHost 512 0 256\n'),patch('inference.subprocess.Popen',return_value=process) as launch,patch('inference.http.client.HTTPConnection',return_value=http),patch('inference.threading.Thread'):
|
|
self.worker.ensure(self.profile)
|
|
args=launch.call_args.args[0]
|
|
self.assertEqual(args[args.index('--device')+1],'CUDA0')
|
|
self.assertEqual(args[args.index('--mmproj-device')+1],'CUDA1')
|
|
self.assertEqual(self.worker.memory_plan['gpus'][1]['required_mib'],3072)
|
|
self.assertEqual(launch.call_args.kwargs['env']['CUDA_VISIBLE_DEVICES'],'gpu-first,gpu-second')
|
|
self.worker.process=None
|
|
if __name__=='__main__':unittest.main()
|