@@ -131,37 +131,53 @@ public void start() {
131131 },
132132 propertiesFile );
133133
134- // copy built-in LTSM
134+ // Link built-in LTSM weights from the runner-wide cache. These can be hundreds of MB to
135+ // multiple GB; copying them per fork dominates IT startup. Symlinks share read-only weights
136+ // across forks; we fall back to a copy on platforms / filesystems that reject symlinks.
135137 String builtInModelPath = filePrefix + File .separator + BUILT_IN_MODEL_PATH ;
136- new File (builtInModelPath ). mkdirs ( );
138+ File builtInModelDir = new File (builtInModelPath );
137139 try {
138- if (new File ( builtInModelPath ) .exists ()) {
139- PathUtils .deleteDirectory (Paths . get ( builtInModelPath ));
140+ if (builtInModelDir .exists ()) {
141+ PathUtils .deleteDirectory (builtInModelDir . toPath ( ));
140142 }
141143 } catch (NoSuchFileException e ) {
142144 // ignored
143145 }
144- try (Stream <Path > s = Files .walk (Paths .get (CACHE_BUILT_IN_MODEL_PATH ))) {
145- s .forEach (
146- source -> {
147- Path destination =
148- Paths .get (
149- builtInModelPath ,
150- source .toString ().substring (CACHE_BUILT_IN_MODEL_PATH .length ()));
151- logger .info ("AINode copying model weights from {} to {}" , source , destination );
152- try {
153- Files .copy (
154- source ,
155- destination ,
156- LinkOption .NOFOLLOW_LINKS ,
157- StandardCopyOption .COPY_ATTRIBUTES );
158- } catch (IOException e ) {
159- logger .error ("AINode got error copying model weights" , e );
160- throw new RuntimeException (e );
161- }
162- });
163- } catch (Exception e ) {
164- logger .error ("AINode got error copying model weights" , e );
146+ Path cacheRoot = Paths .get (CACHE_BUILT_IN_MODEL_PATH );
147+ Path destRoot = builtInModelDir .toPath ();
148+ builtInModelDir .getParentFile ().mkdirs ();
149+ try {
150+ Files .createSymbolicLink (destRoot , cacheRoot );
151+ logger .info ("AINode symlinked model weights {} -> {}" , destRoot , cacheRoot );
152+ } catch (UnsupportedOperationException | IOException symlinkErr ) {
153+ logger .warn (
154+ "AINode failed to symlink {} -> {} ({}), falling back to copy" ,
155+ destRoot ,
156+ cacheRoot ,
157+ symlinkErr .toString ());
158+ builtInModelDir .mkdirs ();
159+ try (Stream <Path > s = Files .walk (cacheRoot )) {
160+ s .forEach (
161+ source -> {
162+ Path destination =
163+ Paths .get (
164+ builtInModelPath ,
165+ source .toString ().substring (CACHE_BUILT_IN_MODEL_PATH .length ()));
166+ logger .info ("AINode copying model weights from {} to {}" , source , destination );
167+ try {
168+ Files .copy (
169+ source ,
170+ destination ,
171+ LinkOption .NOFOLLOW_LINKS ,
172+ StandardCopyOption .COPY_ATTRIBUTES );
173+ } catch (IOException e ) {
174+ logger .error ("AINode got error copying model weights" , e );
175+ throw new RuntimeException (e );
176+ }
177+ });
178+ } catch (Exception e ) {
179+ logger .error ("AINode got error copying model weights" , e );
180+ }
165181 }
166182
167183 // start AINode
0 commit comments