From e019f233f9acd128b18cb8800fbb2393bb8cf520 Mon Sep 17 00:00:00 2001 From: Liangsheng Yin Date: Sun, 16 Nov 2025 22:48:35 +0800 Subject: [PATCH] Remove unused code / testcases in `lang` (#13335) --- python/sglang/lang/compiler.py | 231 ---------------------------- python/sglang/lang/ir.py | 5 - test/lang/run_suite.py | 2 - test/lang/test_anthropic_backend.py | 24 --- test/lang/test_tracing.py | 129 ---------------- test/lang/test_vertexai_backend.py | 53 ------- 6 files changed, 444 deletions(-) delete mode 100644 python/sglang/lang/compiler.py delete mode 100644 test/lang/test_anthropic_backend.py delete mode 100644 test/lang/test_tracing.py delete mode 100644 test/lang/test_vertexai_backend.py diff --git a/python/sglang/lang/compiler.py b/python/sglang/lang/compiler.py deleted file mode 100644 index 1284232f7..000000000 --- a/python/sglang/lang/compiler.py +++ /dev/null @@ -1,231 +0,0 @@ -import multiprocessing -from concurrent.futures import ThreadPoolExecutor -from queue import Queue -from typing import List, Union - -from sglang.global_config import global_config -from sglang.lang.interpreter import ProgramState, StreamExecutor, cache_program -from sglang.lang.ir import SglArgument, SglExpr, SglSamplingParams, SglVariable - - -def compile_func(function, backend): - tracer = function.trace(backend=backend) - compiler = CompiledFunction(tracer, function) - return compiler - - -class CompiledFunction: - def __init__(self, tracer, function): - self.function = function - - self.last_node = CompGraphNode(tracer.last_node) - self.expr_to_node = {} - self.build_graph(tracer) - self.topological_sort() - - def build_graph(self, tracer): - self.nodes = [self.last_node] - self.expr_to_node[tracer.last_node] = self.nodes[-1] - - rename_pid = {} - - visited = set([tracer.last_node]) - head = 0 - while head < len(self.nodes): - cur_node = self.nodes[head] - - # add prev node - prev_node = cur_node.expr.prev_node - if prev_node is not None: - if prev_node not in visited: - visited.add(prev_node) - self.nodes.append(CompGraphNode(prev_node)) - self.expr_to_node[prev_node] = self.nodes[-1] - cur_node.prev_node = self.expr_to_node[prev_node] - self.expr_to_node[prev_node].add_next_node(cur_node) - - # add source node - if isinstance(cur_node.expr, SglVariable): - if cur_node.expr.name in tracer.variables: - source = tracer.variables[cur_node.expr.name].source - else: - source = cur_node.expr.source - if source not in visited: - visited.add(source) - self.nodes.append(CompGraphNode(source)) - self.expr_to_node[source] = self.nodes[-1] - cur_node.source_node = self.expr_to_node[source] - self.expr_to_node[source].add_next_node(cur_node) - head += 1 - - # rename pid - if cur_node.expr.pid not in rename_pid: - rename_pid[cur_node.expr.pid] = len(rename_pid) - cur_node.expr.pid = rename_pid[cur_node.expr.pid] - - def topological_sort(self): - prevd = {} - cand = Queue() - for x in self.nodes: - prevd[x] = (x.prev_node is not None) + (x.source_node is not None) - if prevd[x] == 0: - cand.put(x) - new_list = [] - while cand.qsize() > 0: - head = cand.get() - new_list.append(head) - for x in head.next_nodes: - prevd[x] -= 1 - if prevd[x] == 0: - cand.put(x) - self.nodes = new_list - - def print_graph( - self, - ): - for node in self.nodes: - print(node) - - def run_internal( - self, - backend, - kwargs, - default_sampling_para, - ): - stream_executor_ids = set([x.expr.pid for x in self.nodes]) - stream_executors = {} - for x in stream_executor_ids: - arguments = kwargs if x == self.last_node.expr.pid else {} - stream_executors[x] = StreamExecutor( - backend, arguments, default_sampling_para, None, False - ) - for node in self.nodes: - se_id = node.expr.pid - expr = node.expr - if isinstance(expr, SglVariable): - # Make a copy for SglVariable - expr = SglVariable(expr.name, expr.source) - expr.source_stream_executor = stream_executors[ - node.source_node.expr.pid - ] - elif isinstance(expr, SglArgument): - # Substitute SglArgument - expr = kwargs[expr.name] - stream_executors[se_id].submit(expr) - for stream_executor in stream_executors.values(): - stream_executor.end() - return ProgramState(stream_executors[self.last_node.expr.pid]) - - def run( - self, - *, - max_new_tokens: int = 128, - stop: Union[str, List[str]] = (), - temperature: float = 1.0, - top_p: float = 1.0, - top_k: int = -1, - min_p: float = 0.0, - frequency_penalty: float = 0.0, - presence_penalty: float = 0.0, - backend=None, - **kwargs, - ): - backend = backend or global_config.default_backend - - kwargs.update(self.function.bind_arguments) - - default_sampling_para = SglSamplingParams( - max_new_tokens=max_new_tokens, - stop=stop, - temperature=temperature, - top_p=top_p, - top_k=top_k, - min_p=min_p, - frequency_penalty=frequency_penalty, - presence_penalty=presence_penalty, - ) - - return self.run_internal(backend, kwargs, default_sampling_para) - - def run_batch( - self, - batch_kwargs, - *, - max_new_tokens: int = 128, - stop: Union[str, List[str]] = (), - temperature: float = 1.0, - top_p: float = 1.0, - top_k: int = -1, - min_p: float = 0.0, - frequency_penalty: float = 0.0, - presence_penalty: float = 0.0, - backend=None, - num_threads: Union[str, int] = "auto", - ): - assert isinstance(batch_kwargs, (list, tuple)) - if len(batch_kwargs) == 0: - return [] - assert isinstance(batch_kwargs[0], dict) - - backend = backend or global_config.default_backend - - default_sampling_para = SglSamplingParams( - max_new_tokens=max_new_tokens, - stop=stop, - temperature=temperature, - top_p=top_p, - top_k=top_k, - min_p=min_p, - frequency_penalty=frequency_penalty, - presence_penalty=presence_penalty, - ) - - # Extract prefix by tracing and cache it - if len(batch_kwargs) > 1: - cache_program(self.function, backend) - - # Run all programs - if num_threads == "auto": - num_threads = multiprocessing.cpu_count() - num_threads = min(num_threads, len(batch_kwargs)) - - if num_threads == 1: - rets = [] - for arguments in batch_kwargs: - rets.append( - self.run_internal(backend, arguments, default_sampling_para) - ) - else: - with ThreadPoolExecutor(num_threads) as executor: - futures = [] - for arguments in batch_kwargs: - futures.append( - executor.submit( - self.run_internal, backend, arguments, default_sampling_para - ) - ) - rets = [f.result() for f in futures] - rets[-1].sync() - - return rets - - -class CompGraphNode: - def __init__( - self, expr: SglExpr, prev_node=None, next_nodes=None, source_node=None - ): - self.expr = expr - self.next_nodes = next_nodes or [] - self.prev_node = prev_node - self.source_node = source_node - - def add_next_node(self, other): - self.next_nodes.append(other) - - def __repr__(self): - re = f"stream {self.expr.pid:2d}: " - re += f"%{self.expr.node_id} = " - if self.prev_node is not None: - re += f"%{self.prev_node.expr.node_id} + " - re += repr(self.expr) - return re diff --git a/python/sglang/lang/ir.py b/python/sglang/lang/ir.py index ad690f0f3..43da723b8 100644 --- a/python/sglang/lang/ir.py +++ b/python/sglang/lang/ir.py @@ -313,11 +313,6 @@ class SglFunction: backend = backend or global_config.default_backend return cache_program(self, backend) - def compile(self, *, backend=None): - from sglang.lang.compiler import compile_func - - return compile_func(self, backend) - def __call__(self, *args, **kwargs): from sglang.lang.tracer import TracingScope diff --git a/test/lang/run_suite.py b/test/lang/run_suite.py index 04efba51f..14690d935 100644 --- a/test/lang/run_suite.py +++ b/test/lang/run_suite.py @@ -6,8 +6,6 @@ from sglang.test.test_utils import TestFile, run_unittest_files suites = { "per-commit": [ TestFile("test_srt_backend.py"), - # Skip this due to some OPENAI_API_KEY issues - # "test_openai_backend.py", ], } diff --git a/test/lang/test_anthropic_backend.py b/test/lang/test_anthropic_backend.py deleted file mode 100644 index be4d5921c..000000000 --- a/test/lang/test_anthropic_backend.py +++ /dev/null @@ -1,24 +0,0 @@ -import unittest - -from sglang import Anthropic, set_default_backend -from sglang.test.test_programs import test_mt_bench, test_stream -from sglang.test.test_utils import CustomTestCase - - -class TestAnthropicBackend(CustomTestCase): - backend = None - - @classmethod - def setUpClass(cls): - cls.backend = Anthropic("claude-3-haiku-20240307") - set_default_backend(cls.backend) - - def test_mt_bench(self): - test_mt_bench() - - def test_stream(self): - test_stream() - - -if __name__ == "__main__": - unittest.main() diff --git a/test/lang/test_tracing.py b/test/lang/test_tracing.py deleted file mode 100644 index 3f02ac52b..000000000 --- a/test/lang/test_tracing.py +++ /dev/null @@ -1,129 +0,0 @@ -import unittest - -import sglang as sgl -from sglang.lang.backend.base_backend import BaseBackend -from sglang.lang.chat_template import get_chat_template -from sglang.test.test_utils import CustomTestCase - - -class TestTracing(CustomTestCase): - def test_few_shot_qa(self): - @sgl.function - def few_shot_qa(s, question): - s += "The following are questions with answers.\n\n" - s += "Q: What is the capital of France?\n" - s += "A: Paris\n" - s += "Q: " + question + "\n" - s += "A:" + sgl.gen("answer", stop="\n") - - tracer = few_shot_qa.trace() - # print(tracer.last_node.print_graph_dfs() + "\n") - - def test_select(self): - @sgl.function - def capital(s): - s += "The capital of France is" - s += sgl.select("capital", ["Paris. ", "London. "]) - s += "It is a city" + sgl.gen("description", stop=".") - - tracer = capital.trace() - # print(tracer.last_node.print_graph_dfs() + "\n") - - def test_raise_warning(self): - @sgl.function - def wrong(s, question): - s += f"I want to ask {question}" - - try: - tracer = wrong.trace() - raised = False - except TypeError: - raised = True - - assert raised - - def test_multi_function(self): - @sgl.function - def expand(s, tip): - s += ( - "Please expand the following tip into a detailed paragraph:" - + tip - + "\n" - ) - s += sgl.gen("detailed_tip") - - @sgl.function - def tip_suggestion(s, topic): - s += "Here are 2 tips for " + topic + ".\n" - - s += "1." + sgl.gen("tip_1", stop=["\n", ":", "."]) + "\n" - s += "2." + sgl.gen("tip_2", stop=["\n", ":", "."]) + "\n" - - branch1 = expand(tip=s["tip_1"]) - branch2 = expand(tip=s["tip_2"]) - - s += "Tip 1: " + branch1["detailed_tip"] + "\n" - s += "Tip 2: " + branch2["detailed_tip"] + "\n" - s += "In summary" + sgl.gen("summary") - - compiled = tip_suggestion.compile() - # compiled.print_graph() - - sgl.set_default_backend(sgl.OpenAI("gpt-3.5-turbo-instruct")) - state = compiled.run(topic="staying healthy") - # print(state.text() + "\n") - - states = compiled.run_batch( - [ - {"topic": "staying healthy"}, - {"topic": "staying happy"}, - {"topic": "earning money"}, - ], - temperature=0, - ) - # for s in states: - # print(s.text() + "\n") - - def test_role(self): - @sgl.function - def multi_turn_chat(s): - s += sgl.user("Who are you?") - s += sgl.assistant(sgl.gen("answer_1")) - s += sgl.user("Who created you?") - s += sgl.assistant(sgl.gen("answer_2")) - - backend = BaseBackend() - backend.chat_template = get_chat_template("llama-2-chat") - - compiled = multi_turn_chat.compile(backend=backend) - # compiled.print_graph() - - def test_fork(self): - @sgl.function - def tip_suggestion(s): - s += ( - "Here are three tips for staying healthy: " - "1. Balanced Diet; " - "2. Regular Exercise; " - "3. Adequate Sleep\n" - ) - - forks = s.fork(3) - for i in range(3): - forks[i] += f"Now, expand tip {i+1} into a paragraph:\n" - forks[i] += sgl.gen(f"detailed_tip") - - s += "Tip 1:" + forks[0]["detailed_tip"] + "\n" - s += "Tip 2:" + forks[1]["detailed_tip"] + "\n" - s += "Tip 3:" + forks[2]["detailed_tip"] + "\n" - s += "In summary" + sgl.gen("summary") - - tracer = tip_suggestion.trace() - # print(tracer.last_node.print_graph_dfs()) - - a = tip_suggestion.run(backend=sgl.OpenAI("gpt-3.5-turbo-instruct")) - # print(a.text()) - - -if __name__ == "__main__": - unittest.main() diff --git a/test/lang/test_vertexai_backend.py b/test/lang/test_vertexai_backend.py deleted file mode 100644 index 83ce7fc0b..000000000 --- a/test/lang/test_vertexai_backend.py +++ /dev/null @@ -1,53 +0,0 @@ -import unittest - -from sglang import VertexAI, set_default_backend -from sglang.test.test_programs import ( - test_expert_answer, - test_few_shot_qa, - test_image_qa, - test_mt_bench, - test_parallel_decoding, - test_parallel_encoding, - test_stream, -) -from sglang.test.test_utils import CustomTestCase - - -class TestVertexAIBackend(CustomTestCase): - backend = None - - @classmethod - def setUpClass(cls): - cls.backend = VertexAI("gemini-1.5-pro-001") - - def test_few_shot_qa(self): - set_default_backend(self.backend) - test_few_shot_qa() - - def test_mt_bench(self): - set_default_backend(self.backend) - test_mt_bench() - - def test_expert_answer(self): - set_default_backend(self.backend) - test_expert_answer(check_answer=False) - - def test_parallel_decoding(self): - set_default_backend(self.backend) - test_parallel_decoding() - - def test_parallel_encoding(self): - set_default_backend(self.backend) - test_parallel_encoding() - - def test_image_qa(self): - set_default_backend(self.backend) - test_image_qa() - - def test_stream(self): - set_default_backend(self.backend) - test_stream() - - -if __name__ == "__main__": - unittest.main()