AdarshSingh7647 commited on
Commit
847ec2c
·
verified ·
1 Parent(s): 8af6681

Add merged Qwen3 8B TabRank reranker model card and task image

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ tokenizer.json filter=lfs diff=lfs merge=lfs -text
README.md ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: apache-2.0
3
+ base_model: Qwen/Qwen3-8B
4
+ library_name: transformers
5
+ pipeline_tag: text-generation
6
+ tags:
7
+ - table-ranking
8
+ - listwise-reranking
9
+ - table-retrieval
10
+ - table-question-answering
11
+ - qwen3
12
+ language:
13
+ - en
14
+ ---
15
+ # TabRankSingleTableCoTCond
16
+
17
+ ![task](tabrank_task.png)
18
+
19
+ A single call generative listwise reranker for table retrieval built on Qwen3 8B.
20
+ Given a question and a set of candidate tables the model returns the tables ordered
21
+ from most to least useful for answering the question. It reads all candidates in one
22
+ prompt and emits the full ranking in a single generation.
23
+
24
+ This checkpoint is the **Single Table Reasoning Conditioned** variant.
25
+
26
+ ## What this variant does
27
+
28
+ The model is trained with a short reasoning hint added to the prompt and learns to produce the ranking conditioned on that guidance. It is the strongest variant in our evaluation on most datasets while staying fast at inference.
29
+
30
+ ## Training data
31
+
32
+ This model is trained on the **NQ Tables** training split only which contains single table retrieval questions. The sibling checkpoint [TabRankMultiTableCoTCond](https://huggingface.co/AdarshSingh7647/TabRankMultiTableCoTCond)
33
+ uses the other training mix with the same objective.
34
+
35
+ ## Input and output format
36
+
37
+ The user message lists candidate tables as blocks headed by `### Table 1` `### Table 2`
38
+ and so on. The model returns a JSON object whose value is the ranked list of one based
39
+ candidate positions best first:
40
+
41
+ ```json
42
+ {"ranked_tables": [3, 1, 5, 2, 4]}
43
+ ```
44
+
45
+ Map those positions back to your table ids to obtain the reranked list.
46
+
47
+ ## Evaluation
48
+
49
+ Scored as a listwise reranker that reorders a first stage top 25 candidate list on four
50
+ table question answering benchmarks. SQA and TAT QA use the full test split. HybridQA and
51
+ TabFact use a fixed shared 500 query sample. `acc@10` counts a query correct only when every
52
+ gold table falls inside the top 10.
53
+
54
+ | Dataset | n | recall@10 | ndcg@10 | acc@10 | MRR |
55
+ |---|---|---|---|---|---|
56
+ | SQA | 148 | 0.893 | 0.764 | 0.838 | 0.735 |
57
+ | TAT QA | 362 | 0.666 | 0.546 | 0.431 | 0.637 |
58
+ | HybridQA | 500 | 0.882 | 0.790 | 0.796 | 0.833 |
59
+ | TabFact | 500 | 0.809 | 0.726 | 0.634 | 0.817 |
60
+ | **Mean** | | **0.812** | **0.707** | **0.675** | **0.755** |
61
+
62
+ ## Usage with vLLM
63
+
64
+ ```python
65
+ from vllm import LLM, SamplingParams
66
+ from transformers import AutoTokenizer
67
+
68
+ repo = "AdarshSingh7647/TabRankSingleTableCoTCond"
69
+ tok = AutoTokenizer.from_pretrained(repo)
70
+ llm = LLM(model=repo, dtype="bfloat16", max_model_len=32768)
71
+
72
+ system = ("You are a table relevance expert. Given a question and a set of candidate tables "
73
+ "rank them from most to least useful for answering the question. Reason in a "
74
+ "<think>...</think> block then output exactly JSON with key ranked_tables.")
75
+ user = "Question: ...\n\n### Table 1\n...\n\n### Table 2\n...\n"
76
+
77
+ msgs = [{"role": "system", "content": system}, {"role": "user", "content": user}]
78
+ text = tok.apply_chat_template(msgs, tokenize=False, add_generation_prompt=True)
79
+ # the model writes a <think> block then the ranking json
80
+ out = llm.generate([text], SamplingParams(temperature=0.6, top_p=0.95, max_tokens=8192))
81
+ print(out[0].outputs[0].text)
82
+ ```
83
+
84
+ ## Usage with Transformers
85
+
86
+ ```python
87
+ import torch
88
+ from transformers import AutoModelForCausalLM, AutoTokenizer
89
+
90
+ repo = "AdarshSingh7647/TabRankSingleTableCoTCond"
91
+ tok = AutoTokenizer.from_pretrained(repo)
92
+ model = AutoModelForCausalLM.from_pretrained(repo, torch_dtype=torch.bfloat16, device_map="auto")
93
+
94
+ system = ("You are a table relevance expert. Given a question and a set of candidate tables "
95
+ "rank them from most to least useful for answering the question. Reason in a "
96
+ "<think>...</think> block then output exactly JSON with key ranked_tables.")
97
+ user = "Question: ...\n\n### Table 1\n...\n\n### Table 2\n...\n"
98
+
99
+ msgs = [{"role": "system", "content": system}, {"role": "user", "content": user}]
100
+ text = tok.apply_chat_template(msgs, tokenize=False, add_generation_prompt=True)
101
+ inputs = tok(text, return_tensors="pt").to(model.device)
102
+ out = model.generate(**inputs, max_new_tokens=8192, temperature=0.6, top_p=0.95, do_sample=True)
103
+ print(tok.decode(out[0][inputs.input_ids.shape[1]:], skip_special_tokens=True))
104
+ ```
105
+
106
+ ## Model details
107
+
108
+ * Base model Qwen3 8B
109
+ * Method LoRA rank 16 fine tuning merged into the base weights so it loads directly
110
+ * Precision bfloat16 single file safetensors near 16 GB
111
+ * Family the six TabRank checkpoints span three objectives (Answer Only, Reasoning Generation,
112
+ Reasoning Conditioned) across two training mixes (Single Table, Single plus Multi Table)
113
+
114
+ ## Citation
115
+
116
+ The MultiTabQA data comes from RAG over Tables. Please cite it when using the Single plus
117
+ Multi Table checkpoints:
118
+
119
+ ```bibtex
120
+ @misc{zou2025ragtableshierarchicalmemory,
121
+ title={RAG over Tables: Hierarchical Memory Index, Multi-Stage Retrieval, and Benchmarking},
122
+ author={Jiaru Zou and Dongqi Fu and Sirui Chen and Xinrui He and Zihao Li and Yada Zhu and Jiawei Han and Jingrui He},
123
+ year={2025},
124
+ eprint={2504.01346},
125
+ archivePrefix={arXiv},
126
+ primaryClass={cs.CL},
127
+ url={https://arxiv.org/abs/2504.01346}
128
+ }
129
+ ```
130
+
131
+ The accompanying TabRank paper is currently under review. A citation will be added here once it
132
+ is available on arXiv.
chat_template.jinja ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {%- if tools %}
2
+ {{- '<|im_start|>system\n' }}
3
+ {%- if messages[0].role == 'system' %}
4
+ {{- messages[0].content + '\n\n' }}
5
+ {%- endif %}
6
+ {{- "# Tools\n\nYou may call one or more functions to assist with the user query.\n\nYou are provided with function signatures within <tools></tools> XML tags:\n<tools>" }}
7
+ {%- for tool in tools %}
8
+ {{- "\n" }}
9
+ {{- tool | tojson }}
10
+ {%- endfor %}
11
+ {{- "\n</tools>\n\nFor each function call, return a json object with function name and arguments within <tool_call></tool_call> XML tags:\n<tool_call>\n{\"name\": <function-name>, \"arguments\": <args-json-object>}\n</tool_call><|im_end|>\n" }}
12
+ {%- else %}
13
+ {%- if messages[0].role == 'system' %}
14
+ {{- '<|im_start|>system\n' + messages[0].content + '<|im_end|>\n' }}
15
+ {%- endif %}
16
+ {%- endif %}
17
+ {%- set ns = namespace(multi_step_tool=true, last_query_index=messages|length - 1) %}
18
+ {%- for message in messages[::-1] %}
19
+ {%- set index = (messages|length - 1) - loop.index0 %}
20
+ {%- if ns.multi_step_tool and message.role == "user" and message.content is string and not(message.content.startswith('<tool_response>') and message.content.endswith('</tool_response>')) %}
21
+ {%- set ns.multi_step_tool = false %}
22
+ {%- set ns.last_query_index = index %}
23
+ {%- endif %}
24
+ {%- endfor %}
25
+ {%- for message in messages %}
26
+ {%- if message.content is string %}
27
+ {%- set content = message.content %}
28
+ {%- else %}
29
+ {%- set content = '' %}
30
+ {%- endif %}
31
+ {%- if (message.role == "user") or (message.role == "system" and not loop.first) %}
32
+ {{- '<|im_start|>' + message.role + '\n' + content + '<|im_end|>' + '\n' }}
33
+ {%- elif message.role == "assistant" %}
34
+ {%- set reasoning_content = '' %}
35
+ {%- if message.reasoning_content is string %}
36
+ {%- set reasoning_content = message.reasoning_content %}
37
+ {%- else %}
38
+ {%- if '</think>' in content %}
39
+ {%- set reasoning_content = content.split('</think>')[0].rstrip('\n').split('<think>')[-1].lstrip('\n') %}
40
+ {%- set content = content.split('</think>')[-1].lstrip('\n') %}
41
+ {%- endif %}
42
+ {%- endif %}
43
+ {%- if loop.index0 > ns.last_query_index %}
44
+ {%- if loop.last or (not loop.last and reasoning_content) %}
45
+ {{- '<|im_start|>' + message.role + '\n<think>\n' + reasoning_content.strip('\n') + '\n</think>\n\n' + content.lstrip('\n') }}
46
+ {%- else %}
47
+ {{- '<|im_start|>' + message.role + '\n' + content }}
48
+ {%- endif %}
49
+ {%- else %}
50
+ {{- '<|im_start|>' + message.role + '\n' + content }}
51
+ {%- endif %}
52
+ {%- if message.tool_calls %}
53
+ {%- for tool_call in message.tool_calls %}
54
+ {%- if (loop.first and content) or (not loop.first) %}
55
+ {{- '\n' }}
56
+ {%- endif %}
57
+ {%- if tool_call.function %}
58
+ {%- set tool_call = tool_call.function %}
59
+ {%- endif %}
60
+ {{- '<tool_call>\n{"name": "' }}
61
+ {{- tool_call.name }}
62
+ {{- '", "arguments": ' }}
63
+ {%- if tool_call.arguments is string %}
64
+ {{- tool_call.arguments }}
65
+ {%- else %}
66
+ {{- tool_call.arguments | tojson }}
67
+ {%- endif %}
68
+ {{- '}\n</tool_call>' }}
69
+ {%- endfor %}
70
+ {%- endif %}
71
+ {{- '<|im_end|>\n' }}
72
+ {%- elif message.role == "tool" %}
73
+ {%- if loop.first or (messages[loop.index0 - 1].role != "tool") %}
74
+ {{- '<|im_start|>user' }}
75
+ {%- endif %}
76
+ {{- '\n<tool_response>\n' }}
77
+ {{- content }}
78
+ {{- '\n</tool_response>' }}
79
+ {%- if loop.last or (messages[loop.index0 + 1].role != "tool") %}
80
+ {{- '<|im_end|>\n' }}
81
+ {%- endif %}
82
+ {%- endif %}
83
+ {%- endfor %}
84
+ {%- if add_generation_prompt %}
85
+ {{- '<|im_start|>assistant\n' }}
86
+ {%- if enable_thinking is defined and enable_thinking is false %}
87
+ {{- '<think>\n\n</think>\n\n' }}
88
+ {%- endif %}
89
+ {%- endif %}
config.json ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "architectures": [
3
+ "Qwen3ForCausalLM"
4
+ ],
5
+ "attention_bias": false,
6
+ "attention_dropout": 0.0,
7
+ "bos_token_id": 151643,
8
+ "dtype": "bfloat16",
9
+ "eos_token_id": 151645,
10
+ "head_dim": 128,
11
+ "hidden_act": "silu",
12
+ "hidden_size": 4096,
13
+ "initializer_range": 0.02,
14
+ "intermediate_size": 12288,
15
+ "layer_types": [
16
+ "full_attention",
17
+ "full_attention",
18
+ "full_attention",
19
+ "full_attention",
20
+ "full_attention",
21
+ "full_attention",
22
+ "full_attention",
23
+ "full_attention",
24
+ "full_attention",
25
+ "full_attention",
26
+ "full_attention",
27
+ "full_attention",
28
+ "full_attention",
29
+ "full_attention",
30
+ "full_attention",
31
+ "full_attention",
32
+ "full_attention",
33
+ "full_attention",
34
+ "full_attention",
35
+ "full_attention",
36
+ "full_attention",
37
+ "full_attention",
38
+ "full_attention",
39
+ "full_attention",
40
+ "full_attention",
41
+ "full_attention",
42
+ "full_attention",
43
+ "full_attention",
44
+ "full_attention",
45
+ "full_attention",
46
+ "full_attention",
47
+ "full_attention",
48
+ "full_attention",
49
+ "full_attention",
50
+ "full_attention",
51
+ "full_attention"
52
+ ],
53
+ "max_position_embeddings": 40960,
54
+ "max_window_layers": 36,
55
+ "model_type": "qwen3",
56
+ "num_attention_heads": 32,
57
+ "num_hidden_layers": 36,
58
+ "num_key_value_heads": 8,
59
+ "pad_token_id": null,
60
+ "rms_norm_eps": 1e-06,
61
+ "rope_parameters": {
62
+ "rope_theta": 1000000,
63
+ "rope_type": "default"
64
+ },
65
+ "sliding_window": null,
66
+ "tie_word_embeddings": false,
67
+ "transformers_version": "5.7.0",
68
+ "use_cache": true,
69
+ "use_sliding_window": false,
70
+ "vocab_size": 151936
71
+ }
generation_config.json ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "bos_token_id": 151643,
3
+ "do_sample": true,
4
+ "eos_token_id": [
5
+ 151645,
6
+ 151643
7
+ ],
8
+ "pad_token_id": 151643,
9
+ "temperature": 0.6,
10
+ "top_k": 20,
11
+ "top_p": 0.95,
12
+ "transformers_version": "5.7.0"
13
+ }
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0b292a3f18c79d2c2f591f93212240793730d2f85e8d61d8902939b10486c6a7
3
+ size 16381517208
tabrank_task.png ADDED
tokenizer.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:be75606093db2094d7cd20f3c2f385c212750648bd6ea4fb2bf507a6a4c55506
3
+ size 11422650
tokenizer_config.json ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_prefix_space": false,
3
+ "backend": "tokenizers",
4
+ "bos_token": null,
5
+ "clean_up_tokenization_spaces": false,
6
+ "eos_token": "<|im_end|>",
7
+ "errors": "replace",
8
+ "extra_special_tokens": [
9
+ "<|im_start|>",
10
+ "<|im_end|>",
11
+ "<|object_ref_start|>",
12
+ "<|object_ref_end|>",
13
+ "<|box_start|>",
14
+ "<|box_end|>",
15
+ "<|quad_start|>",
16
+ "<|quad_end|>",
17
+ "<|vision_start|>",
18
+ "<|vision_end|>",
19
+ "<|vision_pad|>",
20
+ "<|image_pad|>",
21
+ "<|video_pad|>"
22
+ ],
23
+ "is_local": true,
24
+ "local_files_only": false,
25
+ "model_max_length": 131072,
26
+ "pad_token": "<|endoftext|>",
27
+ "padding_side": "right",
28
+ "split_special_tokens": false,
29
+ "tokenizer_class": "Qwen2Tokenizer",
30
+ "unk_token": null
31
+ }