Interpolation using the selected config group option in Hydra - fb-hydra

I am using hydra composition with the following structure:
├── configs
│   ├── config.yaml
│   ├── data
│   │   ├── dataset_01.yaml
│   │   └── dataset_02.yaml
│   └── model
│   ├── bert.yaml
│   └── gpt.yaml
config.yaml
defaults:
- model: bert
- data: dataset_01
...
data/dataset_01.yaml
# #package _group_
name: "dataset_01"
train:
path: "../resources/datasets/dataset_01/train.jsonl"
num_samples: 1257391
test:
path: "../resources/datasets/dataset_01/test.jsonl"
num_samples: 71892
val:
path: "../resources/datasets/dataset_01/val.jsonl"
num_samples: 73805
model/bert.yaml
# #package _group_
name: "bert"
encoder: "source.encoder.BertEncoder.BertEncoder"
encoder_hparams:
architecture: "bert-base-uncased"
lr: 1e-7
tokenizer:
architecture: "bert-base-uncased"
predictions:
path: "../resources/predictions/bert_predictions.pt"
entry point
#hydra.main(config_path="configs/", config_name="config.yaml")
def perform_tasks(hparams):
model = MyModel(hparams.model)
if __name__ == '__main__':
perform_tasks()
In the context of hparams.model, there is no way for OmegaConf to interpolate the key data.name since it is not in scope.
So, it would be great if there was an approach to causes the interpolation at the beginning of the application.

OmegaConf interpolation is absolute and is operating on the final config.
Try this:
With Hydra 1.1 or newer you can use hydra.runtime.choices which is a dictionary containing the config groups you have selected.
You will be able to interpolate without adding the name field using hydra:runtime.choices.GROUP_NAME:
predictions:
path: "dir/bert_${hydra:runtime.choices.GROUP_NAME}_pred.pt"

Related

Overwriting hydra configuration groups from CLI

I am trying to overwrite from the CLI a group of parameters and I am not sure how to do it. The structure of my conf is the following
conf
├── config.yaml
├── optimizer
│ ├── adamw.yaml
│ ├── adam.yaml
│ ├── default.yaml
│ └── sgd.yaml
├── task
│ ├── default.yaml
│ └── nlp
│ ├── default_seq2seq.yaml
│ ├── summarization.yaml
│ └── text_classification.yaml
My task/default looks like this
# #package task
defaults:
- _self_
- /optimizer/adam#cfg.optimizer
_target_: src.core.task.Task
_recursive_: false
cfg:
prefix_sep: ${training.prefix_sep}
while the optimiser/default looks like this
_target_: null
lr: ${training.lr}
weight_decay: 0.001
no_decay:
- bias
- LayerNorm.weight
and one specific optimiser, say adam.yaml, looks like this
defaults:
- default
_target_: torch.optim.Adam
In the end the config I'd like to be computed is like this
task:
_target_: src.task.nlp.nli_generation.task.NLIGenerationTask
_recursive_: false
cfg:
prefix_sep: ${training.prefix_sep}
optimizer:
_target_: torch.optim.Adam
lr: ${training.lr}
weight_decay: 0.001
no_decay:
- bias
- LayerNorm.weight
I would like to be able to modify the optimiser via the CLI (say, use sgd), but I am not sure how to achieve this. I tried, but I understand why it fails, this
python train.py task.cfg.optimizer=sgd # fails
python train.py task.cfg.optimizer=/optimizer/sgd #fails
Any tips on how to achieve this?
Github discussion here.
You can't override default list entries in this form.
See this.
In particular:
CONFIG : A config to use when creating the output config. e.g. db/mysql, db/mysql#backup.
GROUP_DEFAULT : An overridable config. e.g. db: mysql, db#backup: mysql.
To be able to override a default list entry, you need to define it as a GROUP_DEFAULT.
In your case, it might look like
defaults:
- _self_
- /optimizer#cfg.optimizer: adam

Using multiple configs in the same group to interpolate values in a yaml file

In Hydra I have the following configuration:
├── conf
│ ├── config.yaml
│ ├── callbacks
│ │ ├── callback_01.yaml
│ │ └── callback_02.yaml
│ └── trainer
│ ├── default.yaml
The callbacks have a structure like this:
_target_: callback_to_instantiate
I need to pass to the trainer/default.yaml both the callbacks through interpolation.
I tried like this:
_target_: pytorch_lightning.Trainer
callbacks:
- ${callbacks.callback_01}
- ${callbacks.callback_02}
With the config.yaml like this:
defaults:
- _self_
- trainer: default
I did also other trials but it doesn't seem to work. Is there a way to interpolate like that in a yaml file by using two or more yaml files that are in the config group?
I would like if possible to keep this structure.
Currently the recommended approach is:
compose a mapping whose values are the desired callbacks, and then
use the oc.dict.values OmegaConf resolver to get a list of values from that dictionary.
# conf/config.yaml
defaults:
- callbacks#_callback_dict.cb1: callback_01
- callbacks#_callback_dict.cb2: callback_02
- trainer: default
- _self_
# conf/trainer/default.yaml
_target_: pytorch_lightning.Trainer
callbacks: ${oc.dict.values:_callback_dict}
# my_app.py
from typing import Any
import hydra
from omegaconf import DictConfig, OmegaConf
#hydra.main(config_path="conf", config_name="config")
def app(cfg: DictConfig) -> Any:
OmegaConf.resolve(cfg)
del cfg._callback_dict
print(OmegaConf.to_yaml(cfg))
if __name__ == "__main__":
app()
At the command line:
$ python my_app.py
trainer:
_target_: pytorch_lightning.Trainer
callbacks:
- _target_: callback_to_instantiate_01
- _target_: callback_to_instantiate_02
For reference, there is an open issue on Hydra's github repo advocating for an improved user experience around

When do you need aggregate over dependsOn

When doing a multiproject build, you can list the projects you depend upon in dependsOn, and tasks will run on the dependencies first, so you can depend on their results.
There also is an aggregate task that, eh, aggregates subprojects. How does aggregating and depending on subprojects differ, and in what cases should you use aggregrate instead of dependsOn
The key difference is aggregate does not modify classpath and does not establish ordering between sub-projects. Consider the following multi-project build consisting of root, core and util projects:
├── build.sbt
├── core
│   ├── src
│   └── target
├── project
│   ├── build.properties
│   └── target
├── src
│   ├── main
│   └── test
├── target
│   ├── scala-2.13
│   └── streams
└── util
├── src
└── target
where
core/src/main/scala/example/Core.scala:
package example
object Core {
def foo = "Core.foo"
}
util/src/main/scala/example/Util.scala
package example
object Util {
def foo =
"Util.foo" + Core.foo // note how we depend on source from another project here
}
src/main/scala/example/Hello.scala:
package example
object Hello extends App {
println(42)
}
Note how Util.foo has a classpath dependency on Core.foo from core project. If we now try to establish "dependency" using aggregate like so
lazy val root = (project in file(".")).aggregate(core, util)
lazy val util = (project in file("util"))
lazy val core = (project in file("core"))
and then execute compile from root project
root/compile
it will indeed attempt to compile all the aggregated projects however Util will fail compilation because it is missing a classpath dependency:
sbt:aggregate-vs-dependsOn> root/compile
[info] Compiling 1 Scala source to /Users/mario/IdeaProjects/aggregate-vs-dependson/target/scala-2.13/classes ...
[info] Compiling 1 Scala source to /Users/mario/IdeaProjects/aggregate-vs-dependson/core/target/scala-2.13/classes ...
[info] Compiling 1 Scala source to /Users/mario/IdeaProjects/aggregate-vs-dependson/util/target/scala-2.13/classes ...
[error] /Users/mario/IdeaProjects/aggregate-vs-dependson/util/src/main/scala/example/Util.scala:5:18: not found: value Core
[error] "Util.foo" + Core.foo // note how we depend on source from another project here
[error] ^
[error] one error found
[error] (util / Compile / compileIncremental) Compilation failed
[error] Total time: 1 s, completed 13-Oct-2019 12:35:51
Another way of seeing this is to execute show util/dependencyClasspath which should have Core dependency missing from output.
On the other hand, dependsOn will modify classpath and establish appropriate ordering between projects
lazy val root = (project in file(".")).aggregate(core, util)
lazy val util = (project in file("util")).dependsOn(core)
lazy val core = (project in file("core"))
Now root/compile gives
sbt:aggregate-vs-dependsOn> root/compile
[info] Compiling 1 Scala source to /Users/mario/IdeaProjects/aggregate-vs-dependson/target/scala-2.13/classes ...
[info] Compiling 1 Scala source to /Users/mario/IdeaProjects/aggregate-vs-dependson/core/target/scala-2.13/classes ...
[info] Compiling 1 Scala source to /Users/mario/IdeaProjects/aggregate-vs-dependson/util/target/scala-2.13/classes ...
[success] Total time: 1 s, completed 13-Oct-2019 12:40:25
and show util/dependencyClasspath shows Core on the classpath:
sbt:aggregate-vs-dependsOn> show util/dependencyClasspath
[info] * Attributed(/Users/mario/IdeaProjects/aggregate-vs-dependson/core/target/scala-2.13/classes)
Finally, aggregate and dependsOn are not mutually exclusive, in fact, it is common practice to use both at the same time, often aggregate on the root all sub-projects to aid building, whilst using dependsOn to handcraft particular orderings for particular sub-projects.

BridgeInner configuration file location

Should the bridge read the path to its certificates from bridge.conf? I think so (as explained in the doc) but when I start it, it looks for certificates in ./certificates/ folder:
[ERROR] 16:17:53+0200 [main] internal.BridgeStartup.run - Exception during bridge startup
java.nio.file.NoSuchFileException: /opt/corda/bridge/certificates/truststore.jks
Here is the block in bridge.conf:
bridgeMode = BridgeInner
outboundConfig {
artemisBrokerAddress = "myNodeServer:myNodeServerPort"
}
bridgeInnerConfig {
floatAddresses = ["floatServer:floatServerPort"]
expectedCertificateSubject = "CN=Float Local,O=Local Only,L=Paris,C=FR"
customSSLConfiguration {
keyStorePassword = "xxx"
trustStorePassword = "xxx"
sslKeystore = "./bridgecerts/bridge.jks"
trustStoreFile = "./bridgecerts/trust.jks"
crlCheckSoftFail = true
}
}
networkParametersPath = network-parameters
Below the tree :
myServerName:/opt/corda/bridge $ tree .
.
├── bridgecerts
│   ├── bridge.jks
│   └── trust.jks
├── bridge.conf
├── corda-bridgeserver-3.1.jar
├── logs
│   └── node-myServerName.log
└── network-parameters
2 directories, 6 files
Something I did wrong here ?
The weird thing is that I don't have this issue with the float on another server, set up the same way...
The bridge has two connections:
One to the float, called the tunnel connection
One to the node, called the Artemis connection
The settings in the bridgeInnerConfig block configure the tunnel connection. The exception you're seeing is for missing certificates for the Artemis connection. See the docs here:
In particular the BridgeInner setup needs a certificates folder
containing the sslkeystore.jks and truststore.jks copied from the
node and a copied network-parameters file in the workspace folder.
You need to provide the certificates folder and network-parameters file as described.
You can also configure the Artemis connection using an outboundConfig block, but it is not recommended.

Nginx routing config for multi language

I have a static website using nginx as server, get some issues when I want to implement multi-lang it.
the final output I want is:
mywebsite.dev -> get en-US/index.html
mywebsite.dev/about -> get en-US/about.html
mywebsite.dev/en-US/index.html -> get en-US/index.html
mywebsite.dev/en-US/about.html -> get en-US/about.html
mywebsite.dev/js-JP/index.html -> get js-JP/index.html
Instead, I got (which is obvious, but I don't have any clue to solve this)
mywebsite.dev -> get en-US/index.html
mywebsite.dev/about -> get 404 not found
mywebsite.dev/en-US/index.html -> get en-US/index.html
mywebsite.dev/en-US/about.html -> get en-US/about.html
mywebsite.dev/js-JP/index.html -> get js-JP/index.html
Folder tree:
output folder
├── img/
├── js/
├── css/
├── en-US
│ ├── about.html
│ └── index.html
└── js-JP
├── about.html
└── index.html
nginx config:
server {
listen 80;
server_name mywebsite.dev www.mywebsite.dev;
access_log /tmp/mywebsite.access.log;
error_log /tmp/mywebsite.error.log;
root /Users/path/to/output/folder;
index en-US/index.html;
}
Is it possible to just modify nginx config to do that?

Resources