| 779 | return attentionNames; |
| 780 | } |
| 781 | static SubModuleIO _getSubModuleIO(std::vector<MNN::Express::VARP> inputs, const SubModuleInfo& info, const void* buffer, size_t bufferSize, std::string srcpath) { |
| 782 | // Deep clone output to let the module release |
| 783 | SubModuleIO io; |
| 784 | std::vector<std::string> inputNames(info.inputs.size()); |
| 785 | std::vector<std::string> outputNames(info.outputs.size()); |
| 786 | auto net = flatbuffers::GetRoot<Net>(buffer); |
| 787 | for (int i=0; i<info.inputs.size(); ++i) { |
| 788 | auto index = info.inputs[i]; |
| 789 | inputNames[i] = net->tensorName()->GetAsString(index)->str(); |
| 790 | } |
| 791 | for (int i=0; i<info.outputs.size(); ++i) { |
| 792 | auto index = info.outputs[i]; |
| 793 | outputNames[i] = net->tensorName()->GetAsString(index)->str(); |
| 794 | } |
| 795 | auto attentionNames = _getAttentionName(buffer, bufferSize); |
| 796 | MNN::ScheduleConfig config; |
| 797 | config.numThread = 1; |
| 798 | std::shared_ptr<MNN::Express::Executor::RuntimeManager> rtmgr(MNN::Express::Executor::RuntimeManager::createRuntimeManager(config)); |
| 799 | rtmgr->setExternalFile((srcpath + ".weight").c_str()); |
| 800 | rtmgr->setMode(MNN::Interpreter::Session_Debug); |
| 801 | std::shared_ptr<MNN::Express::Module> m(MNN::Express::Module::load(inputNames, outputNames, (const uint8_t*)buffer, bufferSize, rtmgr), MNN::Express::Module::destroy); |
| 802 | MNN::TensorCallBackWithInfo beforeCallBack = [&](const std::vector<MNN::Tensor*>& ntensors, const MNN::OperatorInfo* info) { |
| 803 | auto opName = info->name(); |
| 804 | if (info->type() != "Attention") { |
| 805 | return true; |
| 806 | } |
| 807 | if (attentionNames.find(opName) != attentionNames.end()) { |
| 808 | auto query = ntensors[0]; |
| 809 | auto key = ntensors[1]; |
| 810 | auto value = ntensors[2]; |
| 811 | int seq_len = query->length(1); |
| 812 | auto numHead = query->length(2); |
| 813 | auto headDim = query->length(3); |
| 814 | auto kvNumHead = key->length(2); |
| 815 | std::vector<int> kvDims = {kvNumHead, 1, 1, headDim}; |
| 816 | io.kvcache.emplace_back(kvDims); |
| 817 | io.seqLen = seq_len; |
| 818 | } |
| 819 | return true; |
| 820 | }; |
| 821 | MNN::TensorCallBackWithInfo callBack = [&](const std::vector<MNN::Tensor*>& ntensors, const MNN::OperatorInfo* info) { |
| 822 | return true; |
| 823 | }; |
| 824 | MNN::Express::ExecutorScope::Current()->setCallBack(std::move(beforeCallBack), std::move(callBack)); |
| 825 | auto outputs = m->onForward(inputs); |
| 826 | io.inputs = inputs; |
| 827 | io.outputs.resize(outputs.size()); |
| 828 | for (int i=0; i<outputs.size(); ++i) { |
| 829 | io.outputs[i] = MNN::Express::_Clone(outputs[i], true); |
| 830 | } |
| 831 | return io; |
| 832 | } |
| 833 | |
| 834 | static int _compileWholeModule(std::vector<std::string> inputNames, std::vector<std::string> outputNames, |
| 835 | std::vector<std::vector<MNN::Express::VARP>> inputs, const std::set<int>& inputIndexes, |
no test coverage detected