Skip to content

Commit 67b90e0

Browse files
authored
Change project structure - separate main package to three (#105)
* Separate llm-d-inference-sim to 3 packages: llmdinferencesim, common, openaiserverapi: - common package contains general utilities and configuration class - openaiserverapi package contains classes representing input and output structures for v1/chat/completions and v1/completions APIs with relevant utilities - llmdinferencesim package contains the simulator startup and execution implementation Signed-off-by: Maya Barnea <[email protected]> * Move IsValidText utility to a special file in common to be used in tests only Signed-off-by: Maya Barnea <[email protected]> --------- Signed-off-by: Maya Barnea <[email protected]>
1 parent 2b4a79a commit 67b90e0

File tree

15 files changed

+543
-491
lines changed

15 files changed

+543
-491
lines changed

pkg/common/common_suite_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package common_test
2+
3+
import (
4+
"testing"
5+
6+
. "github.com/onsi/ginkgo/v2"
7+
. "github.com/onsi/gomega"
8+
)
9+
10+
func TestCommon(t *testing.T) {
11+
RegisterFailHandler(Fail)
12+
RunSpecs(t, "Common Suite")
13+
}
Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
package llmdinferencesim
17+
package common
1818

1919
import (
2020
"encoding/json"
@@ -27,7 +27,13 @@ import (
2727
"gopkg.in/yaml.v3"
2828
)
2929

30-
type configuration struct {
30+
const (
31+
vLLMDefaultPort = 8000
32+
ModeRandom = "random"
33+
ModeEcho = "echo"
34+
)
35+
36+
type Configuration struct {
3137
// Port defines on which port the simulator runs
3238
Port int `yaml:"port"`
3339
// Model defines the current base model name
@@ -47,7 +53,7 @@ type configuration struct {
4753
// LoraModulesString is a list of LoRA adapters as strings
4854
LoraModulesString []string `yaml:"lora-modules"`
4955
// LoraModules is a list of LoRA adapters
50-
LoraModules []loraModule
56+
LoraModules []LoraModule
5157

5258
// TimeToFirstToken time before the first token will be returned, in milliseconds
5359
TimeToFirstToken int `yaml:"time-to-first-token"`
@@ -103,7 +109,7 @@ type configuration struct {
103109
ObjectToolCallNotRequiredParamProbability int `yaml:"object-tool-call-not-required-field-probability"`
104110
}
105111

106-
type loraModule struct {
112+
type LoraModule struct {
107113
// Name is the LoRA's name
108114
Name string `json:"name"`
109115
// Path is the LoRA's path
@@ -113,27 +119,27 @@ type loraModule struct {
113119
}
114120

115121
// Needed to parse values that contain multiple strings
116-
type multiString struct {
117-
values []string
122+
type MultiString struct {
123+
Values []string
118124
}
119125

120-
func (l *multiString) String() string {
121-
return strings.Join(l.values, " ")
126+
func (l *MultiString) String() string {
127+
return strings.Join(l.Values, " ")
122128
}
123129

124-
func (l *multiString) Set(val string) error {
125-
l.values = append(l.values, val)
130+
func (l *MultiString) Set(val string) error {
131+
l.Values = append(l.Values, val)
126132
return nil
127133
}
128134

129-
func (l *multiString) Type() string {
135+
func (l *MultiString) Type() string {
130136
return "strings"
131137
}
132138

133-
func (c *configuration) unmarshalLoras() error {
134-
c.LoraModules = make([]loraModule, 0)
139+
func (c *Configuration) UnmarshalLoras() error {
140+
c.LoraModules = make([]LoraModule, 0)
135141
for _, jsonStr := range c.LoraModulesString {
136-
var lora loraModule
142+
var lora LoraModule
137143
if err := json.Unmarshal([]byte(jsonStr), &lora); err != nil {
138144
return err
139145
}
@@ -142,13 +148,13 @@ func (c *configuration) unmarshalLoras() error {
142148
return nil
143149
}
144150

145-
func newConfig() *configuration {
146-
return &configuration{
151+
func NewConfig() *Configuration {
152+
return &Configuration{
147153
Port: vLLMDefaultPort,
148154
MaxLoras: 1,
149155
MaxNumSeqs: 5,
150156
MaxModelLen: 1024,
151-
Mode: modeRandom,
157+
Mode: ModeRandom,
152158
Seed: time.Now().UnixNano(),
153159
MaxToolCallIntegerParam: 100,
154160
MaxToolCallNumberParam: 100,
@@ -159,7 +165,7 @@ func newConfig() *configuration {
159165
}
160166
}
161167

162-
func (c *configuration) load(configFile string) error {
168+
func (c *Configuration) Load(configFile string) error {
163169
configBytes, err := os.ReadFile(configFile)
164170
if err != nil {
165171
return fmt.Errorf("failed to read configuration file: %s", err)
@@ -169,10 +175,10 @@ func (c *configuration) load(configFile string) error {
169175
return fmt.Errorf("failed to unmarshal configuration: %s", err)
170176
}
171177

172-
return c.unmarshalLoras()
178+
return c.UnmarshalLoras()
173179
}
174180

175-
func (c *configuration) validate() error {
181+
func (c *Configuration) Validate() error {
176182
if c.Model == "" {
177183
return errors.New("model parameter is empty")
178184
}
@@ -183,7 +189,7 @@ func (c *configuration) validate() error {
183189
c.ServedModelNames = []string{c.Model}
184190
}
185191

186-
if c.Mode != modeEcho && c.Mode != modeRandom {
192+
if c.Mode != ModeEcho && c.Mode != ModeRandom {
187193
return fmt.Errorf("invalid mode '%s', valid values are 'random' and 'echo'", c.Mode)
188194
}
189195
if c.Port <= 0 {

pkg/common/test-helpers.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
Copyright 2025 The llm-d-inference-sim Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package common
18+
19+
import "strings"
20+
21+
// IsValidText validates that the given text could be generated from the predefined list of sentences
22+
// used in tests
23+
func IsValidText(text string) bool {
24+
charsTested := 0
25+
26+
for charsTested < len(text) {
27+
textToCheck := text[charsTested:]
28+
found := false
29+
30+
for _, fakeSentense := range chatCompletionFakeResponses {
31+
if len(textToCheck) <= len(fakeSentense) {
32+
if strings.HasPrefix(fakeSentense, textToCheck) {
33+
found = true
34+
charsTested = len(text)
35+
break
36+
}
37+
} else {
38+
if strings.HasPrefix(textToCheck, fakeSentense) {
39+
charsTested += len(fakeSentense)
40+
// during generation sentences are connected by space, skip it
41+
// additional space at the end of the string is invalid
42+
if text[charsTested] == ' ' && charsTested < len(text)-1 {
43+
charsTested += 1
44+
found = true
45+
}
46+
break
47+
}
48+
}
49+
}
50+
51+
if !found {
52+
return false
53+
}
54+
}
55+
56+
return true
57+
}

0 commit comments

Comments
 (0)