MindSpore Lite显存共享

ACL模型显存共享

注意:纯动态模型不支持激活共享!

显存共享分为work mem共享和weight共享, work mem共享即让多个模型的输入输出的内存共用一块内存, weight共享即让多个模型的权重共享一块内存,下面主要介绍work mem共享。

work mem共享开启时,指定的多个模型将共用一块内存作为公共的work mem,该共用内存的大小为指定模型中的work mem最大的一块,因此work mem共享能够节省许多显存。

当多张卡上的模型需要共享内存时,需要将模型根据其属于的卡分类,并分别指定计算共享的显存大小。在这种情况下将在多张卡上分别申请当前卡上指定模型中最大work mem的内存。

work mem共享python demo:

def init_context(device_id, device_type='ascend'):
  context = mslite.Context()
  context.target = [device_type]
  context.ascend.device_id = device_id
  return context
# 单卡work mem共享demo
model_group = mslite.ModelGroup()
model_group.add_model([path1, path2])
model_group.cal_max_size_of_workspace(mslite.ModelType.MINDIR, init_context(1))
m1 = mslite.Model()
m2 = mslite.Model()
m1.build_from_file(path1, mslite.ModelType.MINDIR, init_context(1))
m2.build_from_file(path2, mslite.ModelType.MINDIR, init_context(1))

#多卡work mem共享demo
model_group = mslite.ModelGroup()
model_group.add_model([path1, path2])
model_group.cal_max_size_of_workspace(mslite.ModelType.MINDIR, init_context(1))
model_group.add_model([path3, path4])
model_group.cal_max_size_of_workspace(mslite.ModelType.MINDIR, init_context(2))
m1 = mslite.Model()
m2 = mslite.Model()
m3 = mslite.Model()
m4 = mslite.Model()
m1.build_from_file(path1, mslite.ModelType.MINDIR, init_context(1))
m2.build_from_file(path2, mslite.ModelType.MINDIR, init_context(1))
m1.build_from_file(path1, mslite.ModelType.MINDIR, init_context(2))
m2.build_from_file(path2, mslite.ModelType.MINDIR, init_context(2))

权重共享

权重共享的原理为,同一个模型的权重相同,并且权重内存为只读内存,所以当出现单个模型在多个线程中初始化的场景时,可以让这些模型使用同一份权重显存,以此节省显存。下列用例为使用单个模型路径在不同线程下是实例化多个模型对象,并进行权重共享:

在接口调用上与work mem共享的差别仅在于初始化model group时使用的flag为mslite。ModelGroupFlag.SHARE_WEIGHT


def test_runtime_general_modelgroup_weightmem_shared_func():
    mod_group_flag = mslite.ModelGroupFlag.SHARE_WEIGHT //指定显存共享类型为权重共享
    device_id_list = [ 0, 0, 0, 0, 0]
    loop = 30
    use_mem = []
    threads = []
    for i in range(5):
        device_id = device_id_list[i]
        t = threading.Thread(target=thread_infer, args=(["xxx/xx.mindir"], ["1, 2, 3, 4:1, 2, 3, 4"], model_group_flag, loop, device_id, use_mem))
        t.start()
        threads.append(t)
    for i in threads:
        t.join()
    print("use_mem: ", use_mem)
    memory_cost = max(use_mem)
    print("memory_cost: ", memory_cost)
    assert 4000 < memory_cost < 4800

GE模型显存共享

GE模型启用内存共享时需要修改代码以及模型config。当前只尝试单卡使用,暂未测试多卡能否使用。

build_from_file时传入如下配置:

[ge_graph_options]
ge.externalWeigth = 1

GE启用内存共享demo:

model_group = mslite.ModelGroup(flags = mslite.ModelGroupFlag.SHARE_WEIGHT) # flag需要指定为mslite.ModelGroupFlag.SHARE_WEIGHT
mode = mslite.Model()
model_vae = mslite.Model()
model_group.add_model([model.model_vae]) # add_model需要在定义模型后即调用,不要再build_from_file后调用
model.build_from_file(model_path, mslite.ModelType.MINDIR, init_context(), config_path = config_file) # config_paht 指定为添加了个。externalWeight=1的配置
model_vae.build_from_file(model_vae_path, mslite.ModelType.MINDIR, init_context(), config_path = config_vae_file)