| 160 | } |
| 161 | |
| 162 | std::pair<VARP, VARP> DiffusionSD35::encode_prompt(const std::string& prompt) { |
| 163 | auto run_encoder = [&](int module_index, VARP input_ids, const char* name) { |
| 164 | auto outputs = mModules[module_index]->onForward({input_ids}); |
| 165 | std::vector<VARP> safe_outputs; |
| 166 | for (auto& out : outputs) { |
| 167 | auto info = out->getInfo(); |
| 168 | const void* ptr = out->readMap<void>(); |
| 169 | auto new_var = _Const(ptr, info->dim, info->order, info->type); |
| 170 | safe_outputs.push_back(new_var); |
| 171 | } |
| 172 | if (mMemoryMode != 1) { |
| 173 | mModules[module_index].reset(); |
| 174 | MNN_PRINT("%s Module unloaded.\n", name); |
| 175 | MNN::Express::Executor::getGlobalExecutor()->gc(MNN::Express::Executor::FULL); |
| 176 | } |
| 177 | return safe_outputs; |
| 178 | }; |
| 179 | |
| 180 | // 1. CLIP L |
| 181 | loadModule(0); |
| 182 | auto ids1 = mTokenizer1->encode(prompt, mMaxTextLen); |
| 183 | VARP input_ids1 = _Input({2, mMaxTextLen}, NCHW, halide_type_of<int>()); |
| 184 | int* inputs1_ptr = input_ids1->writeMap<int>(); |
| 185 | memset(inputs1_ptr, 0, 2 * mMaxTextLen * sizeof(int)); |
| 186 | if (ids1.size() > 0) { |
| 187 | size_t copy_size = std::min(ids1.size(), (size_t)(2 * mMaxTextLen)); |
| 188 | memcpy(inputs1_ptr, ids1.data(), copy_size * sizeof(int)); |
| 189 | } |
| 190 | |
| 191 | auto out1 = run_encoder(0, input_ids1, "CLIP L"); |
| 192 | auto clip_l_hidden = out1[0]; // (2, 77, 768) |
| 193 | auto clip_l_pooled = out1[1]; // (2, 768) |
| 194 | |
| 195 | // 2. CLIP G |
| 196 | loadModule(1); |
| 197 | auto ids2 = mTokenizer2->encode(prompt, mMaxTextLen); |
| 198 | VARP input_ids2 = _Input({2, mMaxTextLen}, NCHW, halide_type_of<int>()); |
| 199 | int* inputs2_ptr = input_ids2->writeMap<int>(); |
| 200 | memset(inputs2_ptr, 0, 2 * mMaxTextLen * sizeof(int)); |
| 201 | if (ids2.size() > 0) { |
| 202 | size_t copy_size = std::min(ids2.size(), (size_t)(2 * mMaxTextLen)); |
| 203 | memcpy(inputs2_ptr, ids2.data(), copy_size * sizeof(int)); |
| 204 | } |
| 205 | |
| 206 | auto out2 = run_encoder(1, input_ids2, "CLIP G"); |
| 207 | auto clip_g_hidden = out2[0]; // (2, 77, 1280) |
| 208 | auto clip_g_pooled = out2[1]; // (2, 1280) |
| 209 | |
| 210 | // 3. T5 |
| 211 | VARP t5_hidden; |
| 212 | loadModule(2); |
| 213 | if (mModules[2]) { |
| 214 | auto ids3 = mTokenizer3->encode(prompt, mMaxTextLenT5); |
| 215 | VARP input_ids3 = _Input({2, mMaxTextLenT5}, NCHW, halide_type_of<int>()); |
| 216 | |
| 217 | // Uncond for T5 is empty string |
| 218 | auto ids3_uncond = mTokenizer3->encode("", mMaxTextLenT5); |
| 219 |
nothing calls this directly
no test coverage detected