推理基础设施 · Python5.4 继承:推理后端的多态
05
基础面向对象 · 4 / 5

5.4 继承:推理后端的多态

💡 vLLM、TGI、TensorRT-LLM 各有细节,但都从同一个 Backend 基类继承

5.4 继承

子类继承父类,复用代码 + 重写方法

class Backend:
    def __init__(self, model_path):
        self.model_path = model_path

    def load(self):
        raise NotImplementedError   # 子类必须实现

class VLLMBackend(Backend):
    def load(self):
        return f"vLLM loading {self.model_path}"

class TGIBackend(Backend):
    def load(self):
        return f"TGI loading {self.model_path}"

关键点

  • class 子类(父类): 写法
  • 子类 __init__ 里通常要 super().__init__(...) 调用父类构造
  • 子类可以重写(override)父类方法实现自己的逻辑
  • isinstance(obj, Backend) 用来检查“是不是这一族”

示范

class Backend:
    def __init__(self, model_path):
        self.model_path = model_path
    def name(self):
        return self.__class__.__name__

class VLLMBackend(Backend):
    pass

class TGIBackend(Backend):
    pass

for cls in (VLLMBackend, TGIBackend):
    eng = cls("qwen2.5-7b")
    print(eng.name(), eng.model_path)

✍️ 练习

  1. 定义基类 InferenceBackend

    • __init__(self, model_path, device="cuda"),存 model_pathdevice
    • 方法 info(self),返回 f"{self.__class__.__name__}({self.model_path}, {self.device})"
  2. 定义子类 MockBackend(InferenceBackend),什么也不加

  3. 定义子类 VLLMBackend(InferenceBackend),重写 info 返回 f"[vllm] {self.model_path} on {self.device}"

测试:

for cls in (MockBackend, VLLMBackend):
    eng = cls("qwen2.5-7b", device="cuda:0")
    print(eng.info())

💡 思路提示

点开看提示
  1. self.__class__.__name__ 自动是当前类的名字
  2. 子类不重写 info() 就继承父类的实现
  3. VLLMBackend 重写后输出格式就不一样了

✅ 参考解法

写不出来再打开
class InferenceBackend:
    def __init__(self, model_path, device="cuda"):
        self.model_path = model_path
        self.device = device

    def info(self):
        return f"{self.__class__.__name__}({self.model_path}, {self.device})"

class MockBackend(InferenceBackend):
    pass

class VLLMBackend(InferenceBackend):
    def info(self):
        return f"[vllm] {self.model_path} on {self.device}"

for cls in (MockBackend, VLLMBackend):
    eng = cls("qwen2.5-7b", device="cuda:0")
    print(eng.info())

🔍 进阶思考

子类 __init__ 不调用 super().__init__(...) 会怎样?

  • 父类的初始化逻辑不会跑
  • self.model_path 这种属性可能没创建
  • 调试时常见 AttributeError

正确写法:

class VLLMBackend(InferenceBackend):
    def __init__(self, model_path, device="cuda"):
        super().__init__(model_path, device)   # ← 必须
        self.engine = "vllm"