File size: 6,458 Bytes
76c8729
 
 
de69528
 
76c8729
 
de69528
76c8729
52798db
 
 
76c8729
 
 
de69528
52798db
de69528
 
 
76c8729
52798db
76c8729
de69528
 
 
 
 
 
 
 
 
 
 
 
52798db
de69528
 
 
 
 
 
 
 
76c8729
de69528
 
 
52798db
de69528
 
 
 
52798db
de69528
 
 
52798db
 
 
de69528
 
 
 
 
 
 
 
76c8729
de69528
76c8729
de69528
 
 
 
 
 
 
8034862
de69528
76c8729
de69528
 
76c8729
de69528
76c8729
de69528
 
 
 
 
76c8729
de69528
 
 
 
 
 
 
76c8729
de69528
76c8729
de69528
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76c8729
de69528
76c8729
 
de69528
 
 
 
 
8034862
de69528
 
d726ed0
0ce5983
 
 
 
 
 
 
 
 
 
8034862
0ce5983
 
8034862
0ce5983
 
 
52798db
 
 
 
 
 
 
 
 
de69528
 
 
 
52798db
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import pandas as pd
import re
import os
from pathlib import Path
from huggingface_hub import InferenceClient
from dotenv import load_dotenv

class DDoSInference:
    def __init__(self):
        """
        Initialize DDoSInference class, set up the API client, and paths for dataset and results.
        """
        load_dotenv()
        self.client = InferenceClient(api_key=os.getenv("HF_TOK_KEY"))
        self.model = "Qwen/Qwen2.5-Coder-32B-Instruct"
        self.dataset_path = Path("~/.dataset/original.csv").expanduser()
        self.results_path = Path("~/.dataset/PROBABILITY_OF_EACH_ROW_DDOS_AND_BENIGN.csv").expanduser()
        self.results_path.parent.mkdir(parents=True, exist_ok=True)

    def process_dataset(self):
        """
        Process the dataset row by row, performing inference using the LLM for each row.
        """
        if not self.dataset_path.exists():
            raise FileNotFoundError("The preprocessed dataset file does not exist. Ensure it is generated using the processor.")

        ddos_data = pd.read_csv(self.dataset_path)

        label_column = " Label"
        if label_column not in ddos_data.columns:
            label_column = input("Enter the label column name in your dataset: ").strip()
            if label_column not in ddos_data.columns:
                raise ValueError(f"Label column '{label_column}' not found in the dataset.")

        ddos_data_without_label = ddos_data.drop([label_column], axis=1)

        stats = {
            'Max': ddos_data_without_label.max(),
            'Min': ddos_data_without_label.min(),
            'Median': ddos_data_without_label.median(),
            'Mean': ddos_data_without_label.mean(),
            'Variance': ddos_data_without_label.var()
        }

        # Generate knowledge prompt
        know_prompt = self.generate_knowledge_prompt(stats)

        # Prepare results DataFrame
        predict_df = self.load_or_create_results()

        start_index = predict_df.shape[0]
        print(f"Starting inference from row {start_index}")

        # Process each row for inference
        for i in range(start_index, ddos_data.shape[0]):
            row_prompt = self.generate_row_prompt(ddos_data.iloc[i])
            probabilities = self.infer_row(know_prompt, row_prompt)
            
            # If no valid response, mark as "None"
            predict_df.loc[i] = [i, *probabilities] if probabilities else [i, "None", "None", "No valid response"]

            # Save after each row for resilience
            predict_df.to_csv(self.results_path, index=False)
            print(f"Processed row {i}: {predict_df.loc[i].to_dict()}")

        print("Inference complete. Results saved at:", self.results_path)

    def generate_knowledge_prompt(self, stats):
        """
        Generates the knowledge prompt based on dataset statistics.
        """
        prompt = (
            "Supposed that you are now an [[ HIGHLY EXPERIENCED NETWORK TRAFFIC DATA ANALYSIS EXPERT ]]. "
            "You need to help me analyze the data in the DDoS dataset and determine whether the data is [[ DDoS traffic ]] or [[ normal traffic ]]. "
            "Here are the maximum, minimum, median, mean, and variance of each column in the dataset to help your judgment:\n"
        )

        for col, values in stats.items():
            prompt += f"{col}: max={values:.2f}, min={values:.2f}, median={values:.2f}, mean={values:.2f}, variance={values:.2f}\n"

        return prompt

    def generate_row_prompt(self, row):
        """
        Generates a row-specific prompt for the LLM.
        """
        row_prompt = (
            "Next, I will give you a piece of data about network traffic information. "
            "You need to tell me the probability of this data being DDoS traffic or normal traffic. "
            "Express the probability in the format [0.xxx, 0.xxx], where the first number represents DDoS probability and the second represents normal traffic probability. "
            "Ensure that the sum of probabilities is exactly 1.\n"
        )

        for col, val in row.items():
            row_prompt += f"{col}: {val}, "

        return row_prompt.strip(', ')

    def infer_row(self, know_prompt, row_prompt):
        """
        Performs inference for a single row using the LLM.
        """
        try:
            messages = [
                {'role': 'user', 'content': know_prompt},
                {'role': 'user', 'content': row_prompt}
            ]

            completion = self.client.chat.completions.create(
                model=self.model,
                messages=messages,
                max_tokens=1000
            )

            response = completion.choices[0].message.content
            probabilities = self.extract_probabilities(response)
            return probabilities

        except Exception as e:
            print(f"Error during inference for row: {e}")
            return None

    def extract_probabilities(self, response):
        """
        Extract probabilities from the LLM response using regex.
        """
        pattern = r'\[(.*?)\]'
        match = re.search(pattern, response)

        if match:
            probs = match.group(1).split(',')
            return [float(p.strip()) for p in probs if p.strip()]
        
        return None

    def get_chat_response(self, user_input):
        """
        Generate a response for the user's question using the LLM.
        """
        try:
            messages = [{'role': 'user', 'content': user_input}]
            completion = self.client.chat.completions.create(
                model=self.model,
                messages=messages,
                max_tokens=500
            )
            
            response = completion.choices[0].message.content
            return response.strip()
            
        except Exception as e:
            return f"Error: Unable to process your request due to {e}."

    def load_or_create_results(self):
        """
        Loads the existing results or creates a new DataFrame if the results file doesn't exist.
        """
        if self.results_path.exists():
            return pd.read_csv(self.results_path)
        else:
            return pd.DataFrame(columns=["index", "attack", "benign", "original"])

# Example usage
if __name__ == "__main__":
    handler = DDoSInference()
    handler.process_dataset()
    print("You can now interact with the model for mitigation steps or download the results.")