# import json # import os # from transformers import AutoTokenizer # from tqdm import tqdm # # ================= 設定區 ================= # MODEL_PATH = "Salesforce/Llama-xLAM-2-8b-fc-r" # MAX_LENGTH = 16384 # INPUT_FILE = "sampled20new_fix2_fix2_toollist_remove_sys_Anyscale_no_tail.jsonl" # 輸入改成 .jsonl # OUTPUT_FILE = "sampled20new_fix2_fix2_toollist_remove_sys_Anyscale_no_tail_dropped.jsonl" # 輸出改成 .jsonl # # ========================================= # def convert_sharegpt_to_standard(conversations): # """ # (同上) 將 ShareGPT 轉換為標準格式以套用 Template # """ # new_messages = [] # for turn in conversations: # role = turn.get('from', '') # content = turn.get('value', '') # if role in ['human', 'user']: # role = 'user' # elif role in ['gpt', 'chatgpt', 'assistant', 'model']: # role = 'assistant' # elif role in ['system']: # role = 'system' # elif role in ['tool', 'function']: # role = 'tool' # new_messages.append({"role": role, "content": content}) # return new_messages # def get_accurate_token_len(tokenizer, entry): # """ # (同上) 使用 apply_chat_template 獲取真實 Token 數 # """ # messages = [] # if "conversations" in entry: # messages = convert_sharegpt_to_standard(entry["conversations"]) # elif "messages" in entry: # messages = entry["messages"] # elif "instruction" in entry: # prompt = entry.get("instruction", "") + "\n" + entry.get("input", "") # response = entry.get("output", "") # messages = [{"role": "user", "content": prompt}, {"role": "assistant", "content": response}] # if not messages: # return len(tokenizer.encode(str(entry), add_special_tokens=False)) # try: # tokenized_ids = tokenizer.apply_chat_template(messages, tokenize=True, add_generation_prompt=False) # return len(tokenized_ids) # except Exception as e: # text = "".join([m['content'] for m in messages]) # return len(tokenizer.encode(text)) # def count_lines(filename): # """計算總行數以便顯示進度條""" # with open(filename, 'rb') as f: # return sum(1 for _ in f) # def main(): # print(f"Loading tokenizer from {MODEL_PATH}...") # try: # tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH, trust_remote_code=True) # except Exception as e: # print(f"Error: {e}") # return # if not os.path.exists(INPUT_FILE): # print(f"File not found: {INPUT_FILE}") # return # # 計算總行數 (非必要,但為了 tqdm 進度條好看) # print("Counting total lines...") # total_lines = count_lines(INPUT_FILE) # print(f"Processing {INPUT_FILE} ({total_lines} lines)...") # dropped_count = 0 # valid_count = 0 # # 使用 'w' 模式打開輸出檔,準備一行行寫入 # with open(INPUT_FILE, 'r', encoding='utf-8') as f_in, \ # open(OUTPUT_FILE, 'w', encoding='utf-8') as f_out: # # 逐行讀取,不佔用大量記憶體 # for line in tqdm(f_in, total=total_lines, desc="Filtering"): # line = line.strip() # if not line: continue # try: # entry = json.loads(line) # except json.JSONDecodeError: # print("Skipping invalid JSON line") # continue # length = get_accurate_token_len(tokenizer, entry) # if length <= MAX_LENGTH: # # 寫入一行 JSON 字串 # f_out.write(json.dumps(entry, ensure_ascii=False) + '\n') # valid_count += 1 # else: # dropped_count += 1 # print(f"\n===== Result =====") # print(f"Original Lines : {total_lines}") # print(f"Dropped Lines : {dropped_count} ({(dropped_count/total_lines)*100:.2f}%)") # print(f"Remaining Lines: {valid_count}") # print(f"Saved to : {OUTPUT_FILE}") # if __name__ == "__main__": # main() import json import os from transformers import AutoTokenizer from tqdm import tqdm # MODEL_PATH = "Salesforce/Llama-xLAM-2-8b-fc-r" # MAX_LENGTH = 16384 # INPUT_FILE = "sampled20new_fix2_fix2_toollist_remove_sys_Anyscale_no_tail.jsonl" # 輸入改成 .jsonl # OUTPUT_FILE = "sampled20new_fix2_fix2_toollist_remove_sys_Anyscale_no_tail_dropped.jsonl" # 輸出改成 .jsonl # ================= 設定區 ================= # MODEL_PATH = "Qwen/Qwen2.5-7B-Instruct" # MODEL_PATH = "meta-llama/Llama-3.1-8B-Instruct" MODEL_PATH = "Salesforce/Llama-xLAM-2-8b-fc-r" MAX_LENGTH = 5120 # multi_turn_miss_func_zh_tw_function_mix_sharegpt.jsonl INPUT_FILE = "multi_turn_miss_func_zh_tw_function_mix_sharegpt.jsonl" # 輸入改成 .jsonl OUTPUT_FILE = "multi_turn_miss_func_zh_tw_function_mix_sharegpt_dropped.jsonl" # 輸出改成 .jsonl DROPPED_FILE = "multi_turn_miss_func_zh_tw_function_mix_sharegpt_too_long.jsonl" # 濾掉的 (Risky) # ========================================= def convert_sharegpt_to_standard(conversations): """將 ShareGPT 轉換為標準格式以套用 Template""" new_messages = [] for turn in conversations: role = turn.get('from', '') content = turn.get('value', '') if role in ['human', 'user']: role = 'user' elif role in ['gpt', 'chatgpt', 'assistant', 'model']: role = 'assistant' elif role in ['system']: role = 'system' elif role in ['tool', 'function']: role = 'tool' new_messages.append({"role": role, "content": content}) return new_messages def get_accurate_token_len(tokenizer, entry): """使用 apply_chat_template 獲取真實 Token 數""" messages = [] if "conversations" in entry: messages = convert_sharegpt_to_standard(entry["conversations"]) elif "messages" in entry: messages = entry["messages"] elif "instruction" in entry: prompt = entry.get("instruction", "") + "\n" + entry.get("input", "") response = entry.get("output", "") messages = [{"role": "user", "content": prompt}, {"role": "assistant", "content": response}] if not messages: return len(tokenizer.encode(str(entry), add_special_tokens=False)) try: tokenized_ids = tokenizer.apply_chat_template(messages, tokenize=True, add_generation_prompt=False) return len(tokenized_ids) except Exception: text = "".join([m['content'] for m in messages]) return len(tokenizer.encode(text)) def count_lines(filename): with open(filename, 'rb') as f: return sum(1 for _ in f) def main(): print(f"Loading tokenizer from {MODEL_PATH}...") try: tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH, trust_remote_code=True) except Exception as e: print(f"Error: {e}") return if not os.path.exists(INPUT_FILE): print(f"File not found: {INPUT_FILE}") return total_lines = count_lines(INPUT_FILE) print(f"Processing {INPUT_FILE} ({total_lines} lines)...") dropped_count = 0 valid_count = 0 # 同時打開三個檔案:讀取原始檔、寫入保留檔、寫入丟棄檔 with open(INPUT_FILE, 'r', encoding='utf-8') as f_in, \ open(OUTPUT_FILE, 'w', encoding='utf-8') as f_valid, \ open(DROPPED_FILE, 'w', encoding='utf-8') as f_dropped: for line in tqdm(f_in, total=total_lines, desc="Filtering"): line = line.strip() if not line: continue try: entry = json.loads(line) except json.JSONDecodeError: continue length = get_accurate_token_len(tokenizer, entry) # 準備要寫入的 JSON 字串 json_str = json.dumps(entry, ensure_ascii=False) + '\n' if length <= MAX_LENGTH: f_valid.write(json_str) valid_count += 1 else: # 這裡將過長的數據寫入 dropped file f_dropped.write(json_str) dropped_count += 1 print(f"\n===== Result =====") print(f"Original Lines : {total_lines}") print(f"Valid Lines : {valid_count} -> Saved to {OUTPUT_FILE}") print(f"Dropped Lines : {dropped_count} ({(dropped_count/total_lines)*100:.2f}%) -> Saved to {DROPPED_FILE}") if __name__ == "__main__": main()