Kaynağa Gözat

Merge branch 'feature/dnn-online-fix' of algorithm/recommend-server into feature/dnn-rank-demo

zhaohaipeng 1 ay önce
ebeveyn
işleme
bc3222062d

+ 2 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankStrategy4RegionMergeModelV562.java

@@ -378,6 +378,8 @@ public class RankStrategy4RegionMergeModelV562 extends RankStrategy4RegionMergeM
 
                     Map<String, String> featureMapString = new HashMap<>(featureMapToString);
                     FeatureV6.putVideoStringFeatures("r", rankInfo, featureMapString);
+                    featureMapString.put("r@vid", vid);
+                    FeatureV6.putProfileVideoCrossStringFeature(currentMs, userProfile, historyVideoMap, featureMapString);
                     FeatureV6.putUserNetworkSeqFeature(featureMapString, userNetworkSeqFeature, videoBaseInfoMap);
                     item.featureMapString = featureMapString;
                     return 1;

+ 55 - 3
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/tansform/FeatureV6.java

@@ -606,6 +606,58 @@ public class FeatureV6 {
         }
     }
 
+    /**
+     * 提取 c9 序列特征的 String 原始值(week/hour/cate1/cate2),供 DNN 模型使用。
+     * 离线 FG 编码直接取原始值(如 week="3"),在线也需要对齐。
+     */
+    public static void putProfileVideoCrossStringFeature(long currentMs, UserShareReturnProfile profile,
+                                                         Map<String, Map<String, String>> hVideoMap,
+                                                         Map<String, String> featureMapString) {
+        if (null == profile) {
+            return;
+        }
+        putRSCrossStringFeature(false, "c9_mss", currentMs, seqMaxN, profile.getM_s_s(), hVideoMap, featureMapString);
+        putRSCrossStringFeature(false, "c9_mrs", currentMs, seqMaxN, profile.getM_r_s(), hVideoMap, featureMapString);
+        putRSCrossStringFeature(true, "c9_lss", currentMs, seqLastN, profile.getL_s_s(), hVideoMap, featureMapString);
+        putRSCrossStringFeature(false, "c9_lrs", currentMs, seqLastN, profile.getL_r_s(), hVideoMap, featureMapString);
+        putRSCrossStringFeature(true, "c9_lr1s", currentMs, seqLastN, profile.getL_r1_s(), hVideoMap, featureMapString);
+    }
+
+    private static void putRSCrossStringFeature(boolean hasCate, String prefix, long currentMs, int maxN,
+                                                 List<UserSRBO> list, Map<String, Map<String, String>> hVideoMap,
+                                                 Map<String, String> featureMapString) {
+        if (null == list || list.isEmpty()) {
+            return;
+        }
+        for (int i = 0; i < list.size() && i < maxN; i++) {
+            UserSRBO u = list.get(i);
+            if (null == u) continue;
+            long id = u.getId();
+            long ts = u.getTs();
+            if (id <= 0) continue;
+
+            String baseKey = String.format("%s@%d", prefix, i + 1);
+
+            // week & hour
+            if (ts > 0) {
+                Calendar calendar = Calendar.getInstance();
+                calendar.setTimeInMillis(ts * 1000);
+                featureMapString.put(baseKey + "_week", String.valueOf(calendar.get(Calendar.DAY_OF_WEEK)));
+                featureMapString.put(baseKey + "_hour", String.valueOf(calendar.get(Calendar.HOUR_OF_DAY) + 1));
+            }
+
+            // cate1 & cate2
+            if (hasCate && null != hVideoMap) {
+                String vid = id + "";
+                Map<String, String> hVideo = hVideoMap.getOrDefault(vid, new HashMap<>());
+                String cate1 = hVideo.getOrDefault("merge_first_level_cate", "").trim();
+                String cate2 = hVideo.getOrDefault("merge_second_level_cate", "").trim();
+                featureMapString.put(baseKey + "_cate1", (!cate1.isEmpty() && !cate1.equals("unknown")) ? cate1 : "");
+                featureMapString.put(baseKey + "_cate2", (!cate2.isEmpty() && !cate2.equals("unknown")) ? cate2 : "");
+            }
+        }
+    }
+
     public static void putVideoStringFeatures(String prefix, Map<String, String> videoInfo, Map<String, String> featureMapToString) {
         featureMapToString.put(prefix + "@resolution", videoInfo.getOrDefault("resolution", ""));
         featureMapToString.put(prefix + "@time_type", videoInfo.getOrDefault("time_type", ""));
@@ -641,15 +693,15 @@ public class FeatureV6 {
         featureMapString.put("act_cate2_seq", String.join(GS_STR, actCate2Seq));
 
         List<String> netVidSeq = FeatureUtils.extractVidsFromUserNetworkSeqFeature(userNetworkSeqFeatureMap, "n_v_s");
-        List<String> netCate1Seq = new ArrayList<>(actVidSeq.size());
-        List<String> netCate2Seq = new ArrayList<>(actVidSeq.size());
+        List<String> netCate1Seq = new ArrayList<>(netVidSeq.size());
+        List<String> netCate2Seq = new ArrayList<>(netVidSeq.size());
         for (String vid : netVidSeq) {
             Map<String, String> videoBaseInfo = videoBaseInfoMap.getOrDefault(vid, new HashMap<>()).getOrDefault("alg_vid_feature_basic_info", new HashMap<>());
             netCate1Seq.add(videoBaseInfo.getOrDefault("merge_first_level_cate", "unknown"));
             netCate2Seq.add(videoBaseInfo.getOrDefault("merge_second_level_cate", "unknown"));
         }
         featureMapString.put("net_cate1_seq", String.join(GS_STR, netCate1Seq));
-        featureMapString.put("met_cate2_seq", String.join(GS_STR, netCate2Seq));
+        featureMapString.put("net_cate2_seq", String.join(GS_STR, netCate2Seq));
     }
 
 

+ 8 - 2
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/score/model/PAIModel.java

@@ -28,7 +28,7 @@ public class PAIModel {
     private PredictClient predictClient;
     private List<Tuple4<String, String, String, TFDataType>> featureKeys = new ArrayList<>();
 
-    private static final PAIModel MODEL = new PAIModel();
+    private static volatile PAIModel MODEL;
 
     private PAIModel() {
         this.fgConfigFilePath = "zhaohaipeng/pai/config/fg/feature_list_20260403.json";
@@ -40,8 +40,14 @@ public class PAIModel {
         this.initPredictClient();
     }
 
-
     public static PAIModel getModelInstance() {
+        if (MODEL == null) {
+            synchronized (PAIModel.class) {
+                if (MODEL == null) {
+                    MODEL = new PAIModel();
+                }
+            }
+        }
         return MODEL;
     }