@@ -20,6 +20,8 @@ limitations under the License.
2020#include < torch_npu/torch_npu.h>
2121
2222#include < cstdlib>
23+ #include < filesystem>
24+ #include < fstream>
2325#include < memory>
2426#include < optional>
2527#include < vector>
@@ -30,6 +32,7 @@ limitations under the License.
3032#include " core/framework/block/block.h"
3133#include " core/framework/block/block_manager_impl.h"
3234#include " core/framework/config/execution_config.h"
35+ #include " core/framework/config/kernel_config.h"
3336#include " core/framework/config/speculative_config.h"
3437#include " core/framework/kv_cache/kv_cache.h"
3538#include " core/framework/kv_cache/kv_cache_utils.h"
@@ -47,6 +50,7 @@ limitations under the License.
4750#include " core/runtime/acl_graph_executor_impl.h"
4851#include " core/runtime/acl_graph_persistent_param.h"
4952#include " core/runtime/base_executor_impl.h"
53+ #include " core/runtime/block_diffusion_model_config.h"
5054#include " core/runtime/dflash_worker_impl.h"
5155#include " core/runtime/mtp_async_state.h"
5256#include " core/runtime/options.h"
@@ -1211,6 +1215,77 @@ TEST(DSparkWorkerOptionsTest, PreservesDraftBlockSize) {
12111215 EXPECT_EQ (dflash_detail::draft_model_num_speculative_tokens (options), 0 );
12121216}
12131217
1218+ TEST (BlockDiffusionConfigTest, MapsCheckpointLayersToNpuCapturePoints) {
1219+ EXPECT_EQ (block_diffusion::map_target_layer_ids_to_capture_points (
1220+ std::vector<int32_t >{0 , 40 , 42 }),
1221+ (std::vector<int32_t >{1 , 41 , 43 }));
1222+ }
1223+
1224+ TEST (BlockDiffusionConfigTest, PreservesDeepseekV4NpuDraftArguments) {
1225+ const std::filesystem::path config_dir =
1226+ std::filesystem::path (::testing::TempDir ()) /
1227+ " xllm_block_diffusion_config_test" ;
1228+ std::filesystem::create_directories (config_dir);
1229+ {
1230+ std::ofstream config_file (config_dir / " config.json" );
1231+ config_file << R"json( {"dspark_target_layer_ids":[40,41,42]})json" ;
1232+ }
1233+
1234+ runtime::Options target_options;
1235+ target_options.speculative_algorithm (" DSpark" )
1236+ .draft_model_path (config_dir.string ())
1237+ .num_speculative_tokens (5 )
1238+ .is_draft_engine (false );
1239+ ModelArgs target_args;
1240+ target_args.model_type (" deepseek_v4" )
1241+ .n_layers (43 )
1242+ .dspark_num_layers (3 )
1243+ .dspark_block_size (0 )
1244+ .compress_ratios ({1 , 1 , 4 });
1245+ block_diffusion::configure_model_args (
1246+ target_args, target_options, /* model_weights_path=*/ " unused" );
1247+ EXPECT_EQ (target_args.model_type (), " deepseek_v4" );
1248+ EXPECT_EQ (target_args.n_layers (), 43 );
1249+ EXPECT_EQ (target_args.dspark_block_size (), 0 );
1250+ EXPECT_EQ (target_args.layers_to_capture (),
1251+ (std::vector<int32_t >{41 , 42 , 43 }));
1252+ EXPECT_EQ (target_args.compress_ratios (), (std::vector<int32_t >{1 , 1 , 4 }));
1253+
1254+ runtime::Options draft_options;
1255+ draft_options.speculative_algorithm (" DSpark" )
1256+ .num_speculative_tokens (5 )
1257+ .is_draft_engine (true );
1258+ ModelArgs draft_args;
1259+ draft_args.model_type (" deepseek_v4" )
1260+ .n_layers (43 )
1261+ .n_hash_layers (2 )
1262+ .dspark_num_layers (3 )
1263+ .dspark_block_size (0 )
1264+ .compress_ratios ({1 , 1 , 4 });
1265+
1266+ KernelConfig& kernel_config = KernelConfig::get_instance ();
1267+ const bool original_native_sas = kernel_config.enable_dspark_native_sas ();
1268+ kernel_config.enable_dspark_native_sas (false );
1269+ block_diffusion::configure_model_args (
1270+ draft_args, draft_options, config_dir.string ());
1271+ kernel_config.enable_dspark_native_sas (original_native_sas);
1272+
1273+ EXPECT_EQ (draft_args.model_type (), " deepseek_v4_dspark" );
1274+ EXPECT_EQ (draft_args.n_layers (), 3 );
1275+ EXPECT_EQ (draft_args.n_hash_layers (), 0 );
1276+ EXPECT_EQ (draft_args.dspark_block_size (), 5 );
1277+ EXPECT_FALSE (draft_args.dspark_use_native_sas ());
1278+ EXPECT_EQ (draft_args.layers_to_capture (), (std::vector<int32_t >{41 , 42 , 43 }));
1279+ EXPECT_EQ (draft_args.compress_ratios (), (std::vector<int32_t >{1 , 1 , 1 }));
1280+
1281+ std::filesystem::remove_all (config_dir);
1282+ }
1283+
1284+ TEST (DSparkNativeSasConfigTest, DefaultsToCompatibilityMode) {
1285+ KernelConfig config;
1286+ EXPECT_FALSE (config.enable_dspark_native_sas ());
1287+ }
1288+
12141289TEST (DSparkWorkerInputTest, InvalidatesTargetAttentionMetadataOnly) {
12151290 ModelInputParams params;
12161291 params.attn_metadata = std::make_shared<layer::AttentionMetadata>();
@@ -1234,16 +1309,17 @@ TEST(DSparkWorkerWeightsTest, PreservesDeepseekDraftHeadAndEmbedding) {
12341309TEST (DSparkSasFallbackTest, ChoosesCompatibleRowsUnlessNativeIsEnabled) {
12351310 ModelArgs draft_args;
12361311 draft_args.model_type (" deepseek_v4_dspark" );
1237- EXPECT_TRUE (dflash_detail::uses_dsa_block_parallel_query_rows (
1238- draft_args, /* sample_from_anchor=*/ true ));
1239- EXPECT_FALSE (dflash_detail::uses_native_dspark_sas (
1240- draft_args, /* sample_from_anchor=*/ true ));
1312+ EXPECT_EQ (dflash_detail::classify_dspark_sas_mode (
1313+ draft_args, /* sample_from_anchor=*/ true ),
1314+ dflash_detail::DSparkSasMode::COMPATIBILITY );
12411315
12421316 draft_args.dspark_use_native_sas (true );
1243- EXPECT_FALSE (dflash_detail::uses_dsa_block_parallel_query_rows (
1244- draft_args, /* sample_from_anchor=*/ true ));
1245- EXPECT_TRUE (dflash_detail::uses_native_dspark_sas (
1246- draft_args, /* sample_from_anchor=*/ true ));
1317+ EXPECT_EQ (dflash_detail::classify_dspark_sas_mode (
1318+ draft_args, /* sample_from_anchor=*/ true ),
1319+ dflash_detail::DSparkSasMode::NATIVE );
1320+ EXPECT_EQ (dflash_detail::classify_dspark_sas_mode (
1321+ draft_args, /* sample_from_anchor=*/ false ),
1322+ dflash_detail::DSparkSasMode::NOT_DSPARK );
12471323}
12481324
12491325TEST (DSparkWorkerWeightsTest, DedicatedVocabularyOverridesFallbackInAnyOrder) {
0 commit comments