当前位置:   article > 正文

QWEN-VL 图文数据标注工具_qwen 微调数据如何标注

qwen 微调数据如何标注

达摩院发布的QWEN系列大模型确实是不错,我们在基础模型对于工业场景/工业图文场景下的判断测评中超过了miniGPT,visualGLM,Owl-PLUG等一众多模态大模型。选定其为开发基座较好。

github链接:GitHub - QwenLM/Qwen-VL: The official repo of Qwen-VL (通义千问-VL) chat & pretrained large vision language model proposed by Alibaba Cloud.

huggingface:https://huggingface.co/Qwen/Qwen-VL

模型部署部分csdn有,出现各种问题可能是transformers版本问题,这里后面再说。

在github中给出了微调数据集的模板:

  1. [
  2. {
  3. "id": "identity_0",
  4. "conversations": [
  5. {
  6. "from": "user",
  7. "value": "你好"
  8. },
  9. {
  10. "from": "assistant",
  11. "value": "我是Qwen-VL,一个支持视觉输入的大模型。"
  12. }
  13. ]
  14. },
  15. {
  16. "id": "identity_1",
  17. "conversations": [
  18. {
  19. "from": "user",
  20. "value": "Picture 1: <img>https://qianwen-res.oss-cn-beijing.aliyuncs.com/Qwen-VL/assets/demo.jpeg</img>\n图中的狗是什么品种?"
  21. },
  22. {
  23. "from": "assistant",
  24. "value": "图中是一只拉布拉多犬。"
  25. },
  26. {
  27. "from": "user",
  28. "value": "框出图中的格子衬衫"
  29. },
  30. {
  31. "from": "assistant",
  32. "value": "<ref>格子衬衫</ref><box>(588,499),(725,789)</box>"
  33. }
  34. ]
  35. },
  36. {
  37. "id": "identity_2",
  38. "conversations": [
  39. {
  40. "from": "user",
  41. "value": "Picture 1: <img>assets/mm_tutorial/Chongqing.jpeg</img>\nPicture 2: <img>assets/mm_tutorial/Beijing.jpeg</img>\n图中都是哪"
  42. },
  43. {
  44. "from": "assistant",
  45. "value": "第一张图片是重庆的城市天际线,第二张图片是北京的天际线。"
  46. }
  47. ]
  48. }
  49. ]

可以选择手撸,为了方便,写了一个简便的标注工具

标注后可以形成按规定的json文件,并把图片也收集到该文件夹中。label.py

  1. import tkinter as tk
  2. from tkinter import filedialog, Label, simpledialog
  3. from PIL import Image, ImageTk
  4. import json
  5. import random
  6. import string
  7. import os
  8. import shutil
  9. import subprocess
  10. import sys
  11. # 创建主窗口
  12. root = tk.Tk()
  13. root.title("Image Viewer with Dialogue")
  14. root.geometry("1000x600") # 设置窗口默认大小
  15. dialogue_entries = [] # 用来存储动态创建的对话输入框
  16. # 加载并显示图片的函数
  17. def load_and_display_image():
  18. global image_label
  19. global image_path
  20. file_path = filedialog.askopenfilename(filetypes=[("Image files", "*.png;*.jpg;*.jpeg")])
  21. image_path = file_path
  22. if file_path:
  23. image = Image.open(file_path)
  24. # 根据原图片宽高比确定图像显示区域的宽度
  25. width = int((400 / image.height) * image.width)
  26. image = image.resize((width, 400), Image.ANTIALIAS)
  27. photo = ImageTk.PhotoImage(image)
  28. if 'image_label' in globals():
  29. image_label.config(image=photo)
  30. else:
  31. image_label = tk.Label(image_frame, image=photo)
  32. image_label.pack(padx=7, pady=7)
  33. image_label.image = photo # keep a reference to the image
  34. # 创建添加对话的按钮
  35. add_dialogue_button = tk.Button(root, text="Add Dialogue", command=add_dialogue_boxes)
  36. add_dialogue_button.pack(side="top", padx=(5, 0), pady=(7, 0))
  37. # 创建保存按钮
  38. save_button = tk.Button(root, text="Save", command=save_to_json)
  39. save_button.pack(side="top", pady=(7, 0))
  40. # 创建文本提示框和输入框
  41. global input_box_1,input_box_2
  42. input_box_1 = create_labeled_input(root, "Input with the picture:")
  43. input_box_2 = create_labeled_input(root, "Assistant:")
  44. # 创建左侧的图片显示框架
  45. image_frame = tk.Frame(root)
  46. image_frame.pack(side="left", anchor="nw", padx=7, pady=7)
  47. # 创建打开图片的按钮
  48. open_button = tk.Button(root, text="Open Image", command=load_and_display_image)
  49. open_button.pack(side="top", pady=(7, 0))
  50. # 创建文本提示框和输入框的函数
  51. def create_labeled_input(parent, label_text):
  52. label = tk.Label(parent, text=label_text)
  53. label.pack(side="top")
  54. entry = tk.Entry(parent, width=50)
  55. entry.pack(side="top")
  56. return entry
  57. # 动态添加对话输入框的函数
  58. def add_dialogue_boxes():
  59. user_entry = create_labeled_input(root, "User:")
  60. assistant_entry = create_labeled_input(root, "Assistant:")
  61. dialogue_entries.append((user_entry, assistant_entry))
  62. # 将输入的文本保存为 JSON 文件的函数
  63. def save_to_json():
  64. save_dir = "saves"
  65. # 生成一个10位的随机字符串作为文件名
  66. random_filename = ''.join(random.choices(string.ascii_lowercase + string.digits, k=10))
  67. # 确保save_dir存在
  68. if not os.path.exists(save_dir):
  69. os.makedirs(save_dir)
  70. # 定义JSON文件的完整路径
  71. json_file_path = os.path.join(save_dir, random_filename + '.json')
  72. # 定义图片文件的完整路径
  73. image_file_path = os.path.join(save_dir, random_filename + '.jpg')
  74. cat1 = "Picture 1: <img>"
  75. cat2 = random_filename
  76. cat3 = ".jpg</img>\n"
  77. cat4 = input_box_1.get()
  78. cat = cat1+cat2+cat3+cat4
  79. dialogue_data = {
  80. "conversations": []
  81. }
  82. dialogue_data["conversations"].append({
  83. "from":"user",
  84. "value": cat
  85. })
  86. dialogue_data["conversations"].append({
  87. "from": "assistant",
  88. "value": input_box_2.get()
  89. })
  90. for user_entry, assistant_entry in dialogue_entries:
  91. dialogue_data["conversations"].append({
  92. "from": "user",
  93. "value": user_entry.get()
  94. })
  95. dialogue_data["conversations"].append({
  96. "from": "assistant",
  97. "assistant": assistant_entry.get()
  98. })
  99. # 把对话数据保存到JSON文件
  100. with open(json_file_path, 'w', encoding='utf-8') as json_file:
  101. json.dump(dialogue_data, json_file, ensure_ascii=False, indent=4)
  102. # 把图片文件保存到指定的文件夹
  103. if image_path and os.path.isfile(image_path):
  104. shutil.copy2(image_path, image_file_path)
  105. subprocess.Popen(["python", "test.py"])
  106. sys.exit()
  107. root.mainloop()

标注后,所有的标注文件和图片在saves文件下,可以在代码中自行更改保存文件夹。

另外需要一个脚本来聚合json文件:merge.py

  1. import os
  2. import json
  3. from collections import OrderedDict
  4. import re
  5. # 刚才标注完的数据目录,建议把merge.py放在其上一级
  6. directory_path = 'saves/'
  7. # 创建一个空列表来存储合并后的内容
  8. merged_data = []
  9. #建议设置成到时候训练用的数据的绝对路径,方便qwen finetune时遍历
  10. image_path_prefix = 'pathtoyourimages/'
  11. # 正则表达式匹配 <img>*.jpg</img>
  12. img_pattern = re.compile(r'<img>(.*?\.jpg)</img>')
  13. # 递归函数来更新图片路径
  14. def update_img_paths(obj):
  15. if isinstance(obj, OrderedDict):
  16. for key, value in obj.items():
  17. if isinstance(value, (OrderedDict, list)):
  18. update_img_paths(value)
  19. elif isinstance(value, str):
  20. obj[key] = img_pattern.sub(
  21. f'<img>{image_path_prefix}\\1<img>', value)
  22. elif isinstance(obj, list):
  23. for i, item in enumerate(obj):
  24. if isinstance(item, (OrderedDict, list)):
  25. update_img_paths(item)
  26. elif isinstance(item, str):
  27. obj[i] = img_pattern.sub(
  28. f'<img>{image_path_prefix}\\1<img>', item)
  29. # 遍历目录中的所有文件
  30. for filename in os.listdir(directory_path):
  31. # 检查文件是否是JSON文件
  32. if filename.endswith('.json'):
  33. # 构建完整的文件路径
  34. file_path = os.path.join(directory_path, filename)
  35. # 打开并读取JSON文件
  36. with open(file_path, 'r', encoding='utf-8') as file:
  37. try:
  38. # 加载JSON内容
  39. content = json.load(file, object_pairs_hook=OrderedDict)
  40. # 创建一个新的OrderedDict以将'id'字段放在最前面
  41. new_content = OrderedDict()
  42. new_content['id'] = os.path.splitext(filename)[0]
  43. new_content.update(content)
  44. update_img_paths(new_content)
  45. # 将此内容添加到合并后的数据列表
  46. merged_data.append(new_content)
  47. except json.JSONDecodeError as e:
  48. print(f"Error reading {filename}: {e}")
  49. # 指定新JSON文件的名称
  50. output_filename = 'merged_data.json'
  51. # 构建完整的输出文件路径
  52. output_filepath = output_filename
  53. # 写入合并后的数据到新的JSON文件
  54. with open(output_filepath, 'w', encoding='utf-8') as output_file:
  55. json.dump(merged_data, output_file, ensure_ascii=False, indent=4)
  56. print(f"Merge complete. Combined file created at {output_filepath}")

在以上文件中,建议将label.py和merge.py,saves文件夹放在同一级,输出后的文件merged_data.json也在这一级文件,之后移动图片到训练数据集文件夹,并更改merge.py中的image_path_prefix路径,即可完成所有标注文件储存。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/406396
推荐阅读
相关标签
  

闽ICP备14008679号